NullReferenceException on StartCoroutine. Does anyone know what it could cause that?
Hello community,
I am getting a run-time error when stating a Coroutine. The calls inherit from a class that, again, inherit from MonoBehaviour and an interface. The class is instantiated run-time and it is not connected to any gameobject available in the current scene. My sample code
public class TaskTrialState: MonoBehaviour, AIState
{
...
}
public class FollowBeaconTimer : TaskTrialState
{
protected override Enter(TaskTrialAI agent)
{
base.Enter(agent);
...
SetBeacon();
}
private void SetBeacon()
{
StartCoroutine(DelayedSetInputState(true,2.5f));
}
private IEnumerator DelayedSetInputState(bool state,float delay)
{
yield return new WaitForSeconds(delay);
SetInputState(true);
}
}
The error has the following text
NullReferenceExceptionUnityEngine.MonoBehaviour.StartCoroutine (IEnumerator routine) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineMonoBehaviourBindings.gen.cs:6
Any idea what could be wrong? Could it be from the simple fact that the script is not attached to a gameobject? Any hint would be very useful, also to help me with a workaround.
Thanks.
$$anonymous$$onoBehaviours should be on a GameObject. Ins$$anonymous$$d of instantiating the class, have you tried making a new GameObject and adding the component?
Classes deriving from $$anonymous$$onoBehavior should normally be attached on gameobjects - this is why you use the parent class, to utilize the classes as components. I am not sure how you instantiate this class, because in the case of a new() keyword, you should already receive a warning in the Editor, suggesting that you should add it as a component ins$$anonymous$$d.
Finally, I am not sure if this is a copy-paste mistake, but SetInputState(true) has no semicolon in the end. Can I also ask where exactly this method is located, which could be the potential reason for the null exception?
Edited the missing ; thanks for spotting it out.
I edited bits of the code to make every step more clear (and also
The FollowBeaconTimer is a state-machine state. The "new" is done when changing state. This is the state-machine base class:
public class State$$anonymous$$achine<T>
{
T agent;
AIState<T> currState = null;
public State$$anonymous$$achine(T _agent)
{
agent = _agent;
}
public void SwitchState(AIState<T> state)
{
if (currState == state)
{
Debug.LogWarning("Switching to the same state: " + state.Name);
}
if (currState != null)
{
currState.Exit(agent);
}
currState = state;
currState.Enter(agent);
}
public void AIUpdate()
{
if (currState != null)
{
currState.Execute(agent);
}
}
}
And another player of all of this is the class (attached to a gameobject) that have has memeber the State$$anonymous$$achine class. In the end I have already solved with a dirty trick. Since I am using coroutines just to delay execution I use the class having the state machine for my coroutine and at the I set a callback to the class the that started it. I am not sure with this structure if I can really solve the problem as I would not like to attach the script to a game object.