- Home /
NullReferenceException on StartCoroutine()
when run my game at some point it calls Act() and I get the following error:
NullReferenceException
UnityEngine.MonoBehaviour.StartCoroutine (IEnumerator routine) (at C:/BuildAgent/work/d63dfc6385190b60/artifacts/EditorGenerated/UnityEngineMonoBehaviour.cs:62)
Wait.Act () (at Assets/Scripts/Actors/Actions/Wait.cs:7)
Actor.NextAction () (at Assets/Scripts/Actors/Actor.cs:43)
Unity tells me the NullReference is on the call to StartCoroutine()
The "Action" class does inherit MonoBehavior
The Code:
using UnityEngine;
using System.Collections;
public class Wait : Action {
public override void Act () {
StartCoroutine(WaitAction());
}
IEnumerator WaitAction() {
yield return new WaitForSeconds(3);
Finished();
}
}
I have Googled the internet to pieces, and read every bit of documentation I could find to understand what I'm doing wrong. So what have I missed?
Answer by Bunny83 · Jul 11, 2014 at 02:05 AM
Well, i just guess that the script (and / or the gameobject it's attached to) has been destroyed, or you created the Wait-instance with "new" which would result in the same behaviour since a MonoBehaviour can't live on it's own.
In C# / .NET / Mono instances actually can't be destroyed since they live in a managed memory environment. Objects are destroyed when all references to the object are gone, no longer valid. After that the garbage collector eventually kicks in and removes the object.
However in Unity, since it's core is written in C++, (native) objects can be destroyed on command (with Destroy to be more precise). The Destroy method actually only destroys the object on the c++ side. The managed representation of the object (your MonoBehaviour script) will still be there since the GC can only collect the object when there are no references anymore. That's why Unity actually "fakes" that the reference is null when the object has lost it's native counterpart.
If you use the "new" keyword to create an instance of a MonoBehaviour derived class the instance doesn't have a native counterpart and will always pretend to be null. If you want to create an instance at runtime it has to be attached to a gameobject. This is done with AddComponent
Yep, the problem was that the object was not added as a component of something in the scene. I had to tweak things kind of weird to make it work but now it does. thanks.
Thanks for the great explaination. I just have a small question about the ter$$anonymous$$ology: by "objects" do you mean the gameobjects in the hierarchy, and by "instances" do you mean something like an instance of a class created by the "new" keyword?
@ComeSweetDeath: An object is an instance of a class ^^ So it actually means the same. The confusing thing which gets most people is, that there are two "worlds" where objects can live: The native C++ world (the actual, underlaying engine) and the managed environment which is used for scripting (C# / UnityScript / Boo).
In both cases "object" or "instance of a class" means the same. An object / instance is actually only made up by the data it contains. All methods belong to the class. So an instance of a class is the "thing" that sits somewhere in your memory and represents the data of that instance / object.
This helped me out so much. THAN$$anonymous$$ YOU!!!!! The headache is FINALLY over!
$$anonymous$$y mistake was i as making a new reference to the unity class that had the erroring Coroutine in it rather than having the class as a component.