Weird NullReferenceException

At this point I have seen this error more then I want to and learned how to deal with it. Today however it just seems weird to me so I don’t even know how to continue fixing this.

When a Enemy is spawn after starting the game I get a NullReference Error telling me there is something wrong in my PathFinding, knowing after previous tests that my Pathfinding works perfectly without Enemies I thought it had to be something else in the EnemyMover (But I could be wrong). i’ve added a few Debugs there to see where it went wrong and it seems like it manages to move a few frames and then stops. This alone already seems really odd to me (If it was a NullReference I would say it would crash instantly) but it turns out that if i just unpause the game everythings works well and as intended. So it is just at the start somewhere. I have no idea what i’ll have to show here that might help so please let me know if you want to see something.

My enemy mover script

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

public class EnemyMover : MonoBehaviour
{
    [SerializeField] [Range(0,5)]float speed = 1f;

    List<Node> path = new List<Node>();

    Enemy  enemy;
    GridManager gridManager;
    PathFinder pathfinder;

    // Start is called before the first frame update
void OnEnable()
    {
        FindPath();
        ReturnToStart();
        StartCoroutine(WalkPath());
    }

void Awake() 
    {
        enemy = FindObjectOfType<Enemy>();
        gridManager = FindObjectOfType<GridManager>();
        pathfinder = FindObjectOfType<PathFinder>();
    }

void FindPath()
    {
        path.Clear();
        path = pathfinder.GetNewPath();
        Debug.Log("Path found");
    }

    void ReturnToStart()
    {
        transform.position = gridManager.GetPositionfromcoordinates(pathfinder.StartCoordinates);
        Debug.Log("ReturnToStart");
    }

void FinishPath()
    {
        gameObject.SetActive(false);
        enemy.StealGold();
    }

IEnumerator WalkPath()
    {
        Debug.Log("WalkStarted");
        for (int i=0; i < path.Count; i++)
    
    {
        float travelPercent = 0f;
 
                Vector3 startPosition = transform.position;
                Vector3 endPosition = gridManager.GetPositionfromcoordinates(path[i].coordinates);
                transform.LookAt(endPosition);
       
        while(travelPercent < 1)
            {
                Debug.Log("while walking going well");
                travelPercent += Time.deltaTime * speed; 
                transform.position = Vector3.Lerp(startPosition,endPosition,travelPercent);
                yield return new WaitForEndOfFrame();
                Debug.Log("Frame restart");
            }
        }

        FinishPath();
    }
}

The error comes from PathFinder. Line 46, to be specific. Check what could possibly be null on that line, and why

Line 46 is my gridManager.ResetNodes():

public List<Node> GetNewPath()
{
        gridManager.ResetNodes();
        BreadthFirstSearch();
        return BuildPath();
}

What is this part in the Gridmanager

    public void ResetNodes()
    {
        foreach(KeyValuePair<Vector2Int, Node> entry in grid)
            {
                entry.Value.connectedTo = null;
                entry.Value.isExplored = false;
                entry.Value.isPath = false;
            }
    }

And it is working perfectly fine when I unpause it. What is the confusing part.

I also don’t get the Error message when the unit is not there, but it’s still being used.

NullReferenceException means that a reference (“link”) to an instance is missing. If the error message points to gridManager.ResetNodes();, gridManager is null.

If your game works correctly, maybe there are multiple GridManager object in your scene and one of them gets destroyed? Or maybe the GridManager component or its game object are disabled at some point?

I have been looking for most of those things but couldn’t find anything wrong.

That however gave me a idea to try.

I didn’t got the error in the lecture that needed me to mess around with the script execution order. So i just gave it a try as well and it fixed the problem. what could explain why it was only a problem at the beginning.

But i am still a bit confused why it was being able to move for a few tics before giving it the error, cus wouldn’t this have meant that it had no path to move on ?

I got it working now but don’t really fully understand why i saw what happend :sweat_smile:.

Unity executes methods with the same name in a random order. If you have, for example, two Awake methods, and they depend on a specific execution order, it might be that everything seems to work perfectly fine except for a few times.

Without being aware of the arbitrary execution order, debugging these unexpected results can be difficult because the code itself makes sense. The arbitrary execution order is a typical source of bugs for game developers using Unity. In the worst case, you never notice any problem until you publish your game and receive messages by angry players complaining about bugs that you cannot reproduce on your own device because of Unity’s arbitrary execution order.

For this reason, always double check the logic of your code if you have dependencies. Sometimes, it makes more sense to move certain lines to the Start method to ensure that other code in the Awake method gets executed first.


See also:

I see ^^

thank you for your advise again Nina.
I was already wondering why there would be a need for the Awake and Start difference (and asume I would find out in time) but this makes sense.

Check the first link at the bottom of my answer. Start gets executed much later than Awake. And “much later” means a few milliseconds (or, as you wrote: “a few tics”). :wink:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms