I’m lost here…
I have an empty game object with 2 scripts attached.
When I duplicate the object in the Hierarchy, the 2nd one throws NullReferenceException error even though its running the same code.
Disabling the first object, and its 2 scripts in the inspector doesn’t make any difference, the copied one still throws the exception.
One script it 600 lines and the second is 400 so I will just show what I hope is relevant.
[RequireComponent(typeof(RandomRoom))]
public class GRID : MonoBehaviour
{
RandomRoom GetRandomRoom;
public List<A_Room> random_room_list = new List<A_Room>();
private void Awake()
{
GetRandomRoom = gameObject.GetComponent<RandomRoom>();
}
void Start()
{
CreateARandomRoom(amountOfRandomRooms, amountOfTriesToBuildRandomRooms);
GetRandomRoom.RoomDoorCreator();
}
void CreateARandomRoom(int roomCount, int stopTrying)
{
random_room_list.Add(new A_Room(" Room_" + random_room_list.Count));
}
}
Error is on: GetRandomRoom.RoomDoorCreator();
GRID.Start () (at Assets/Scripts/MazeBuilder/GRID.cs:17)
public class RandomRoom : MonoBehaviour
{
GRID getGRID;
private void Start()
{
getGRID = gameObject.GetComponent<GRID>();
}
public void RoomDoorCreator()
{
for (int i = 0; i < getGRID.random_room_list.Count; i++)
{
}
}
Error is on: for (int i = 0; i < getGRID.random_room_list.Count; i++)
NullReferenceException: Object reference not set to an instance of an object
RandomRoom.RoomDoorCreator () (at Assets/Scripts/MazeBuilder/RandomRoom.cs:14)
Not that it helps the problem here, but this is what I am playing with.
This is a pure timing issue. You can’t guarantee the order of “Start” to run unless you setup the order yourself. Basically, the Start in GRID runs before the Start in RandomRoom. So, the GRID Start calls the RandomRoom script and tells it to loop through the list, but RandomRoom doesn’t have a reference assigned to getGRID at that point, so you get a null error.
I would suggest having an Init method in RandomRoom that gets called from the Start of GRID that sets the reference, that way you’re not relying on luck on how the scripts execute, but you know it will have the reference before you call RoomDoorCreator.
I just want to say, I approve of your avatar picture and username.
Also, here are some broad tips to fix a NullReferenceException in Unity3D:
http://plbm.com/?p=221
Brathnann’s post is likely spot on, because those sorts of inter-script timing errors are certainly a thing.
1 Like
Thanks, I will look further into it.
It made no sense to me that it worked 100% of the time on 1 gameobject, but would fail 100% of the time on the second gameobject. I thought if the order of operation was working on the first gameobject, then they would all work the same.
I gave up for an hour, then restarted Unity just before bed, first gameobject was still disabled and the second gameobject magically stopped throwing the error… I’d had enough of that Voodoo by then…
I get the Awake > Start > Run.
But there seems to be some more going on underneath in regards to order of operation that I need to account for.
Thanks.
I’m happy that you are curious about this! It’s always good to understand what a system is doing if you hope to interoperate successfully with it.
Perhaps this diagram will make you smile:
https://docs.unity3d.com/Manual/ExecutionOrder.html
Since there are only two reliable layers of startup timing, Awake and Start() , you can’t always get what you want.
I favor actually explicitly starting things wherever necessary. A singleton pattern can help with this, or just flat-out calling the other init function yourself.
Yes, there is no guarantee that one Start method will run first and another second. That’s it. It depends on many things under the hood. The fact that it worked for you 32 times doesn’t mean it would have worked for the 33rd occasion if you adjust something. Like you did, and it broke.
What you can do is that you always grab instance (GetComponent<>, GameObject.Find, etc…) in Awake method and you reserve Start() to initialization.
The guarantee holds that all Awake will run before any Start.
And of course, live long and prosper.