Is a parent object guaranteed to available to its child object?

In my system, I am using a script located on a gameobject located somewhere down in the heirarchy to find the unique ID of an object at a higher point in the heirarchy. This doesn’t have to be the root object, just somewhere higher than the searching object.

In start(), I recurse up the heirarchy looking for a specific script attached to an object using GetComponent() and the first one I find, I get the ID of the transform it is attached to.

I want to think that parent objects are available in this way to any child object. Am I right?

If an object is actually a child of another object, yes of course you can always access it.

Are you aware of this by the way?
https://docs.unity3d.com/ScriptReference/Component.GetComponentInParent.html
This will handle the “searching up the tree” for you.

2 Likes

If a Transform.parent is non-null, the only thing that guarantees is that there is at least ONE Transform immediately above the object in question.

As to what Components are on it, that’s not guaranteed in any way.

You can crawl up yourself, or perhaps consider using either:

GetComponentInParent<T>()

or

GetComponentsInParent<T>()

1 Like

Is this true even for scripts started on child objects? It doesn’t seem reasonable that a child object can be instantiated before its parent, or even that a parent object will be partially instantiated before moving on to a child. I know that the manual states exactly what you have said but still…

By the way I can’t use
GetComponentInParent<T>()
as that returns only a reference to the component and I want a reference to the object.

Once you have a reference to a component, then thatComponentReference.gameObject is the GameObject that has that component.

When a component script gets its Awake, you should not depend on any other object existing except its parent, or any other components except components on the same object. It’s really for you to set up things inside your own component state. OnEnable is your first call where you can depend on everything around you being in the right state for deep initialization such as dependency injection or component searches outside this object.

I’d have to do a test to be 100% sure, but I am already 98% sure that by the time your component gets OnEnable, you can depend on ALL of the children objects that were co-serialized (by scene or prefab instantiation) already existing and their active and enabled components already having had their Awake, and all of the parent objects existing and their enabled components already having had their Awake AND OnEnable.

1 Like

All of the objects in the whole prefab hierarchy will exist by the time any of your code can run, don’t worry about it.

You can still use it just fine. Every component has a .gameObject property if you really need a reference to the GameObject.

MyScript ms = GetComponentInParent<MyScript>();
GameObject theObject = ms.gameObject;
2 Likes

Exactly. When a prefab is instantiated, the whole object is cloned / deserialized before the first Awake is called on that object. The same should be true for scenes that load. Of course the order in which Awake methods may be called depends on many factors. So getting a reference to another object or component should be no problem, but don’t assume the object has initialized itself already. Serialized values should be available immediately

2 Likes

Thanks, all. That confirms what I had assumed/hoped (it isn’t the sort of thing you can comprehensively test for). I am working out of Start() and I only need objects to be there, active or not, and all their components to be present.
And thanks for the heads up about .gameObject on the component - it’ll get rid of at least two lines of code!

You can actually get rid of ALL the code if you can simply drag the references in, aka “Do it the Unity Way™.”

Randomly ransacking the scene hierarchy looking for stuff should always be an absolute last resort.

Otherwise if you’re doing procgen or late-lazy-loading type stuff, then an explicit service locator pattern is definitely better than any form of GetComponent() calls.

And of course…

Remember the first rule of GameObject.Find():

Do not use GameObject.Find();

More information: https://starmanta.gitbooks.io/unitytipsredux/content/first-question.html

More information: https://discussions.unity.com/t/899843/12

2 Likes