- Home /
NullReferenceException and script load order
My problem is that I need to have a class with a variable that holds the count of a number of entities with another class.
To try and solve the problem I have put together some code that simplifies the process:
ChildClassA.cs
using UnityEngine;
using System.Collections;
public class ChildClassA : MonoBehaviour
{
void OnEnable()
{
ControllerClass.childA.entityCount++;
}
void OnDisable()
{
ControllerClass.childA.entityCount--;
}
}
ChildClassAData.cs
using UnityEngine;
using System.Collections;
public class ChildClassAData : MonoBehaviour
{
public int entityCount = 0;
}
ControllerClass.cs
using UnityEngine;
using System.Collections;
public class ControllerClass : MonoBehaviour
{
public static ChildClassAData childA;
// Use this for initialization
void Awake ()
{
childA = GetComponent<ChildClassAData> ();
}
// Update is called once per frame
void Update ()
{
Debug.Log ("A: " + childA.entityCount);
}
}
I receive no Compiler Errors.
When running the game I get a NullReferenceException which I assume is because the child class has tried to access the childA object before it is initialized. If any more of the object are created after this error the code runs smoothly.
Therfore I would like to know how to have the instances of the child class wait for the controller class to be fully initialized before being enabled.
from my understanding, Awake and OnEnable get executed before Start, so this is a bit strange. Perhaps OnEnable is not running before Start? For a test, try using an Awake function in the ChildClassA class, to see if it is that the first enable is running after Start
void OnEnable()
{
ControllerClass.childA.entityCount++;
}
$$anonymous$$ore info :
Scratch that, I derped.
So ChildClassA is running before ControllerClass, that's why the null. ControllerClass has not stored a reference to the ChildClassAData yet. From my last post, Awake and OnEnable get executed before Start.
You could try using Awake in ControllerClass ins$$anonymous$$d of Start.
I spotted this too. Unfortunately it has the same effect. I have edited the script above to show awake ins$$anonymous$$d.
The order of loading was as follows: Child OnEnable() Controller Awake() Child Start()
This seems to contradict the page on Execution times: [http://docs.unity3d.com/$$anonymous$$anual/ExecutionOrder.html][1]
I have found a work around which I have put in an answer below.
Answer by SblandUK · Aug 03, 2014 at 09:03 AM
As this is only a problem for the child's that are there at the start I found a work around as below:
ChildClassA.cs
using UnityEngine;
using System.Collections;
public class ChildClassA : MonoBehaviour
{
public static bool initialized = false;
// Use this for initialization
void Start ()
{
if (!initialized) {
ControllerClass.childA.entityCount++;
initialized = true;
}
}
void OnEnable()
{
if (ControllerClass.childA != null && initialized) {
ControllerClass.childA.entityCount++;
}
}
void OnDisable()
{
ControllerClass.childA.entityCount--;
}
}
Your answer
Follow this Question
Related Questions
Extending a class 1 Answer
array of objects 1 Answer
Trying to change a subclasses' variable 1 Answer
new Monobehaviour as variable returns warning... 1 Answer
Class Casting US/JS - 'foo' is not a member of 'Object' 1 Answer