Question About Unity Class Hierarchy

Hello guys,

I am fairly experienced programmer and I’m aware of OOP concepts. I was reading the Unity Manual and I stumbled upon something that I can’t explain, so I decided to write here. To be more specific I was reading this page:

This example is bothering me

// Require the rocket to be a rigidbody.
// This way we the user can not assign a prefab without rigidbody
public Rigidbody rocket;
public float speed = 10f;

void FireRocket () {
    Rigidbody rocketClone = (Rigidbody) Instantiate(rocket, transform.position, transform.rotation);
    rocketClone.velocity = transform.forward * speed;
    
    // You can also acccess other components / scripts of the clone
    rocketClone.GetComponent<MyRocketScript>().DoSomething();
}

// Calls the fire method when holding down ctrl or mouse
void Update () {
    if (Input.GetButtonDown("Fire1")) {
        FireRocket();
    }
}

Here is the question. Why can we do this on a prefab that has a rigid body component?
Rigidbody rocketClone = (Rigidbody) Instantiate(rocket, transform.position, transform.rotation);

The prefab is of type GameObject if I am correct. GameObject inherits from Object.
The Rigidbody inherits Component. The Compoment class inhetirs from Object too.

I got really confused. Why can we cast the result from Instantiate to type of Rigidbody? Does this mean that when we attach a component (In this case Rigidbody) somekind of inheritance is happening behind the scenes? How does things work behind the scenes? I am somewhat tired and I might not be thinking straight and my question might be silly, but It really got my attention and I want to know how it works.

Regards

This is actually a huge feature of Unity’s component system. Instantiate can actually clone any UnityEngine.Object. So you pass in a source object and get back a clone of it. This works with Meshes, Materials, Textures, and so on. There is a special case when instantiating components. Since Components can’t live on their own (they always need to be attached to a GameObject) when you instantate a Component, the gameobject it contains is also cloned. And when you clone a gameobject all components on that gameobject will be cloned as well. Furthermore, since the Transform component is also cloned, it will also clone all child transforms as well as their gameobjects…

Keep in mind that the actual hierarchy is build by the transform components, not the actual gameobjects. GameObjects are just empty containers.

In most cases you want to make use of this feature. Instantiate will always return the same type that you passed in. So If you pass in a reference to a MonoBehaviour script which is on a prefab, the whole prefab will be instantiated and you get direct access to that script on the newly instantiated object. This saves you a GetComponent call. So whenever you declare a variable to hold a prefab reference, don’t use “GameObject” since it’s the most useless class. If you don’t have any scripts on the prefab, use Transform.

Also keep in mind that the Component class itself also has all the GetComponent methods so you can directly get another component from a component reference.

edit

Just to clear up some confusion. This won’t work:

public GameObject prefab;

Transform inst = (Transform)Instantiate(prefab);

This will throw an invalid casting exception since you instantiated a gameobject reference which you can’t cast to Transform. However this does work:

public YourMonoBehaviourClass prefab;

YourMonoBehaviourClass inst = (YourMonoBehaviourClass)Instantiate(prefab);;

Again, Instantiate returns the exact same type you passed in. You can only assign prefabs / gameobjects to the prefab variable that have a “YourMonoBehaviourClass” component attached. When dragging the object onto the object field in the inspector you don’t assign a GameObject reference but a reference to the “YourMonoBehaviourClass” instance on that gameobject.

Your rocket is a GameObject. That’s right. What happens is just a trick from Unity. Normally, you would paste a Rigidbody component into rocket variable for it to work. But when you paste a GameObject instance into it, it will just search for the first detected Rigidbody component inside that GameObject to use in the script.

The rocket itself is not a Rigidbody. But it has a component Rigidbody at least once. If you attach 2 Rigidbody components to the rocket then Unity will just select one component from those.

I think, they wrote that code for variety. In normal situation, Instantiate method clone a prefab to scene.
I think, they need rigidbody of a gameobject for this example. Here is Instantiate method:

If you read this reference, you can also find how to Instantiate clone script instances directly from a prefab.