NullReferenceException: Object reference not set to an instance of an object in void Awake()

In trying to deal with multiple scripts, I’ve found an odd situation where I can’t access objects if they are placed into the Awake() function, but still can if they are placed into the Update() function.
The code I am talking about is this:

public class PlayerItems : MonoBehaviour
{

    public GameObject playerObject;

    private Items itemData;

    public int selItem;

    private void Start()
    {

        itemData = playerObject.GetComponent<Items>();

    }

    private void Update()
    {

        Debug.Log("This item is called a" + itemData.GetName(selItem) + ". Its description reads \"" + itemData.GetDesc(selItem) + ".\"");

    }

}

Accessing this script on the same object:

public class Items : MonoBehaviour
{

    public bool GetExists(int id)
    {

        if (id > 000)
        {

            return true;

        }
        else
        {

            return false;

        }

    }

    public string GetName(int id)
    {

        if (id == 001)
        {

            return "Sword";

        }
        else
        {

            Debug.LogError("Item ID Not Found");
            return "Error";

        }

    }

    public string GetDesc(int id)
    {

        if (id == 001)
        {

            return "Weapon";

        }
        else
        {

            Debug.LogError("Item ID Not Found");
            return "Error";

        }

    }

}

The code works fine like this, but when I replace Update() with Awake(), it for some reason won’t work, and outputs this error:
NullReferenceException: Object reference not set to an instance of an object
PlayerItems.Awake () (at Assets/Scripts/PlayerItems.cs:25)
Why does this happen? I know that there are other ways to ensure that it only happens for one frame, but I don’t understand why it won’t work on the first.

Awake() is called before Start(), so when you rename Update to Awake you’re trying to use itemData before you give it a reference.

Also, you shouldn’t call methods on other scripts from Awake anyways, because there is no guarantee that the other script has finished initializing. You can use it for getting references though. Just don’t use those references for anything in Awake.

2 Likes

Ah, thank you! For some reason, I thought that Awake was called on frame 1, instead of before start, so that’s a huge mistake on my part.

1 Like

This is helpful when you’re unsure the order of events:

https://docs.unity3d.com/Manual/ExecutionOrder.html

1 Like