- Home /
Script freezing Unity
Hey guys I wrote an AI script that was supposed to make the enemy rotate towards the player once he enters it's trigger collider but everytime I run it unity freezes. Here's the code:
using UnityEngine;
using System.Collections;
public class EnemyAI : MonoBehaviour {
public float speed = 2.0f;
public GameObject target;
public float dist;
// Use this for initialization
void Start () {
GameObject.FindGameObjectWithTag("Player");
}
// Update is called once per frame
void Update () {
dist = Vector3.Distance(transform.position, target.transform.position);
}
void OnTriggerEnter(Collider hit){
while(hit.gameObject.tag == "Player"){
transform.rotation = Quaternion.Lerp(transform.rotation, target.transform.rotation, Time.deltaTime * speed);
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
}
}
PS: I tried "if" instead of "while" but in only worked on rotating the enemy one frame
$$anonymous$$akes sense. It will freeze your game, or at least this GameObject.
void OnTriggerEnter(Collider hit)
receives the Collider, but it won't change inside the function, it is a local instance, so the tag will always be "Player", you'll never leave this loop without telling it to leave.
Yeah I just switched it back to if. If it's not much trouble do you know how to make the enemy look at the player every frame as long as the player's within the trigger area?
Answer by AndyMartin458 · Jan 14, 2014 at 06:09 PM
Oh I see the problem, you need to use the function OnTriggerStay with an if.
void OnTriggerStay(Collider hit)
{
if(hit.gameObject.tag == "Player")
{
transform.rotation = Quaternion.Lerp(transform.rotation, target.transform.rotation, Time.deltaTime * speed);
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
}
In Start(), you should probably recode to "target = GameObject.FindGameObjectWithTag("Player");" or remove your start function altogether. You are probably getting a null reference exception because target is null.
void Start ()
{
target = GameObject.FindGameObjectWithTag("Player");
}
Thanks, yeah I had to drag the player character manually to the target variable in the hierarchy.
@BlackWingsCorp I modified my answer to include OnTriggerStay
Thanks @Andy$$anonymous$$artin458 it worked! Do you know how to make the enemy rotate to the position of the player rather than his rotation? It would be greatly appreciated
I am sorry i couldn't understand this
enemy rotate to the position of the player rather than his rotation
please explain a bit more
in my script the enemy looks towards the rotation of the player in other words wherever the player is looking at the enemy will look at to ins$$anonymous$$d of looking at the player's position
Answer by JoaoOliveira · Jan 14, 2014 at 06:13 PM
The condition you are testing never changes inside the while loop, therefore it is an infinite loop.
What you might want is a field that is changed according to player detection:
private bool _collidingWithPlayer;
void OnTriggerEnter(Collider hit){
if(hit.gameObject.tag == "Player"){
_collidingWithPlayer = true;
}
}
void OnTriggerExit(Collider hit){
if(hit.gameObject.tag == "Player"){
_collidingWithPlayer = false;
}
}
void Update () {
dist = Vector3.Distance(transform.position, target.transform.position);
if(_collidingWithPlayer){
transform.rotation = Quaternion.Lerp(transform.rotation, target.transform.rotation, Time.deltaTime * speed);
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
}
Simple and efficient. Thanks! Any idea on how to make the enemy rotate towards the player's position rather than rotation? I tried to use the transform.LookAt() but didn't work
Answer by woodoo · Jan 14, 2014 at 06:21 PM
You could modify your loop to something like this and probably wou'll get what you want:
void onTriggerEnter(Collider hit)
{
while (true)
{
/* your code here */
/* here you create some collision verification, like OverlapSphere, and if it doesn't collide, you just break and leave the loop */
}
}