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?

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