I’ve got a script in an object, which uses (GetComponentInChildren) in Update to get a reference to a specific potential child.
public ScriptName scriptName;
void Update() {
scriptName = gameObject.GetComponentInChildren<ScriptName>():
}
The reason I’m doing it in Update is that the child will not always be there. The object starts out empty, and the player can add and remove the child at runtime, so I need to make sure the script always has a reference.
What’s weird is I expected this to spew out errors whenever the object didn’t have the child (since it’s trying to get a component from something that isn’t there). But it doesn’t, and it seems to be working fine so far.
But I’m still worried about whether if I actually keep it this way, will there be any problems down the line.
GetComponent isn’t the quickest method to run. Personally, I would have ScriptName populate the field in Awake or OnEnable and have it remove itself in OnDisable or OnDestroy instead or when it is created/destroyed.
GetComponent<> and ist siblings are very expensive performancewise. A better method is to ‘cache’ (store in a global variable) the reference, and test if the reference was lost (is null) before re-aquiring it:
if (cachedScript == null) {
// warning: this will execute each update until
// the script is reaquired
cachedScript = this.gameObject.GetComponentInChildren<ScriptType>();
// if not aquired, exit
if (cachedScript == null)
return
}
// if we get here, we have a valid script
Much better, of course would be if the children notified the parent of connecting and disconnection via Awake() and OnDestroy() as mentioned
The dirty flag pattern to the rescue!
Make a private boolean and set it to true at declaration. In OnTransformHierarchyChanged event, always reset this flag to true. Whenever you want to use child ScriptName, check that flag. If true, update class level cached variable, if not true just return it.