0

I keep getting the NullReferenceException error. Now, I know that unity is telling me that I haven't set an instance of an object correctly but I can't work out what I am doing incorrectly. Here is the code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Wolf : Enemy
{
    private Transform target;
    private Transform home;
    private StickPickup stickScript;
    private bool hasReachedDestination = false;
    private float hunger = 50f;

    // Start is called before the first frame update
    public override void Start()
    {
        base.Start();
        target = sticks.transform;
        home = GameObject.Find("Cave").transform;
    }

    // Update is called once per frame
    void Update()
    {
        hunger -= Time.deltaTime;

        if(hunger <= 40f)
        {
            GoHunting();
        }
        else
        {
            ReturnHome();
        }

    }

    void GoHunting()
    {
        if(target != null)
            {
                if(Vector3.Distance(transform.position, target.position) > 0.1f)
                {
                    transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
                    hasReachedDestination = true;
                    GrabStick();
                }
            }
            else
            {
                CalculateNextStick();
            }
    }

    void CalculateNextStick()
    {
        Debug.Log("test", target);
        target = GameObject.FindGameObjectWithTag("Sticks").transform;
        stickScript = GameObject.FindGameObjectWithTag("Sticks").GetComponent<StickPickup>();
        hasReachedDestination = false;
    }

    void GrabStick()
    {
        bool checkDistance = IsTouching();
        if(checkDistance == true)
        {
            stickScript.DestroySelf();
            hunger = 50f;
        }

    }

    private bool IsTouching()
    {
        if(Vector3.Distance(transform.position, target.position) < 0.1f)
        {
            return true;
        }
        else
        {
            return false;
        }
    }


    void ReturnHome()
    {
        transform.position = Vector3.MoveTowards(transform.position, new Vector3(-16f, 9.38f, 0f), speed * Time.deltaTime);
    }


}

The problem line it's specifically picking up is this one here:

target = GameObject.FindGameObjectWithTag("Sticks").transform;

Also here is the base class that the Wolf inherets from:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{

    [SerializeField] protected float speed;
    [SerializeField] protected bool isScared;
    [SerializeField] protected Transform sticks;
    // Start is called before the first frame update
    public virtual void Start()
    {
        sticks = GameObject.FindGameObjectWithTag("Sticks").transform;
    }

    // Update is called once per frame
    void Update()
    {

    }
}

I am not that great at OOP related programming but it looks like I am assigning it correctly. I am not really sure how to debug this one either. If you have any suggestions that would be awesome.

Opache
  • 3
  • 3
  • 2
    Usual wrong approach here. What if _GameObject.FindGameObjectWithTag("Sticks")_ doesn't find any objects whose tag is "Sticks"? It returns null but your code doesn't care and call _transform_ on a null object. – Steve Apr 19 '20 at 08:57
  • That's a fair point and in this situation its very possible for sticks to not spawn. In fact that's how I recreate the problem. What would be the better way? – Opache Apr 19 '20 at 09:01
  • ```FindGameObjectWithTag``` method returns null, if no GameObject found by given tag. Are you sure you always have a GameObject for "Sticks" tag? Break that line of code on ```var gameObject = GameObject.FindGameObjectWithTag("Sticks")``` and before accessing to its ```transform```property do null checking ```if(gameObject != null) { //access to transform property``` } – Oleg Kyrylchuk Apr 19 '20 at 09:02
  • In the duplicate answers there are lot of better approach at the problem. It boils down to what @OlegKyrylchuk told you in its comment. First get the result, then check for null and only if not null access the returned object properties. You also can use the [_null conditional operator_](https://learn.microsoft.com/en-us/archive/msdn-magazine/2014/october/csharp-the-new-and-improved-csharp-6-0) to keep everything in a single line – Steve Apr 19 '20 at 09:28
  • Thanks guys. That was really good advice. I didn't realise that returning null would basically 'delete' what the target was. I have it checking for null now and then actioning what needs to be done. – Opache Apr 19 '20 at 09:31

0 Answers0