NullReference.Exveption: Object reference not set to an instance of an object
The issue appears to be with the Transform "tgt" on line 54: Could someone explain to me what I'm doing wrong?
using UnityEngine;
using System.Collections;
public class TestEnemyScript : MonoBehaviour {
public GameObject player;
public float speed;
private Transform target;
private float vel;
FieldOfView fov;
CharacterController controller;
Animator animator;
void Start()
{
//store the fov componenet in a variable
fov = GetComponent<FieldOfView>();
//store character controller in variable
controller = GetComponent<CharacterController>();
//store animator in variable
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update ()
{
Anim();
if (fov.visibleTargets != null)
{
foreach(Transform t in fov.visibleTargets)
{
if (t.gameObject.tag == "Player") { target = t;}
}
Move(target);
}
if(animator.GetBool("isDying"))
{
StartCoroutine(Die());
}
}
IEnumerator Die()
{
yield return new WaitForSeconds(5);
animator.SetBool("isDying", false);
Destroy(gameObject);
}
void Move(Transform tgt)
{
if(animator.GetBool("isDying") == false)
{
/*Line 54 */ transform.position = Vector3.MoveTowards(transform.position, new Vector3(tgt.transform.position.x, transform.position.y, tgt.transform.position.z), speed * Time.deltaTime);
transform.LookAt(new Vector3(tgt.transform.position.x, transform.position.y, tgt.transform.position.z));
}
}
void Anim()
{
vel = controller.velocity.magnitude;
Debug.Log(vel);
//isWalking
if (vel != 0)
{
animator.SetBool("isWalking", true);
}
else if (vel == 0)
{
animator.SetBool("isWalking", false);
}
}
}
If none of the visible targets have the player tag applied, "target" will be null.
I fixed it by changing
if(animator.GetBool("isDying") == false)
to
if(animator.GetBool("isDying") == false && tgt != null)
Answer by iabulko · Sep 26, 2016 at 05:55 AM
The problem is that when you calls Move(target); (line 34) target will be null if non of visible objects will be called "Player". Also try to avoid using foreach, instead use for . Foreach creates a new variable for each loop, and afaik if destroys it after the loop is finished, so it will always be null. That's my suggestion:
if (fov.visibleTargets != null)
{
for(int i=0; i< fov.visibleTargets.length; i++)
{
if (fov.visibleTargets[i].gameObject.tag == "Player")
{
target = fov.visibleTargets[i];}
}
if(target != null)
Move(target);
}
while you are correct that variables inside a foreach loop are scoped to the foreach loop, target is a class member, so it will not be cleared when the foreach loop is finished.