1

When I want to instantiate a prefab I do something like this:

[SerializeField] private GameObject myPrefab;
[...]
var a = Instantiate(myPrefab) as GameObject;

Then, if myPrefab has a script MyScript, I can access its methods or variables like this:

a.GetComponent<MyScript>().SomeMethod();

In the book "Unity in Action" in chapter 5 the author uses a different approach:

[SerializeField] private MyScript myScript;
[...]
var a = Instantiate(myScript) as MyScript;
a.SomeMethod();

As far as I understand, in this way I have a shorter sintax to access variables and methods of the script, but I need a longer sintax to access the containing GameObject. (I think something like this: a.GetComponentInParent())

I have not found documentation other than this book about this way of instantiating objects, I would like to hear opinions on this.

2 Answers2

4

Things to understand before reading this answer:

  • Each Prefab or Object in the scene has a GameObject and Transform.
  • Each script/component or GameObject inherits from Object. Because of this, you can instantiate any script/component or GameObject. Just answered this few hours ago so see this post for a complete explanation.

To answer your question, both of them are doing the-same thing. If you pass in component/script to the Instantiate function, Unity will get every script/component and GameObject attached to that script then instantiate them.

Example of how to decide which one to use:

Let's say that you have a GameObject prefab called "bullet" and that bullet has a Rigidbody attached to it. You want to instantiate the bullet on key-press then AddForce to the bullet....

You have two choices:

1.Instantiate the bullet as GameObject then get the Rigidbody from it with GetComponent so that you could add force to it:

public GameObject myPrefab;

void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        GameObject obj = Instantiate(myPrefab) as GameObject;
        obj.GetComponent<Rigidbody>().AddForce(new Vector3(0, 500, 0));
    }
}

2.Instantiate the bullet as Rigidbody then AddForce to it.

public Rigidbody myPrefab;

void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        Rigidbody rb = Instantiate(myPrefab) as Rigidbody;
        rb.AddForce(new Vector3(0, 500, 0));
    }
}

It makes sense to use this version because there is no use of GetComponent. If you only need to access the components then just go with this method.

In the latest version of Unity, this has been simplified a-lot by adding generic version of the Instantiate function so that you don't even need to cast it to the script or Object type which reduces the whole thing into one line of code:

public Rigidbody myPrefab;

void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        //Instantiate and Addforce on one line
        Instantiate(myPrefab).AddForce(new Vector3(0, 500, 0));
    }
}

but I need a longer sintax to access the containing GameObject. (I think something like this: a.GetComponentInParent())

Like my second comment, each script has a GameObject. All you need to do is scriptName.gameObject to get the GameObject of that script and scriptName.transform to get the Transform of that GameObject.

For example:

void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        Rigidbody rb = Instantiate(myPrefab) as Rigidbody;
        rb.AddForce(new Vector3(0, 500, 0));

        GameObject obj = rb.gameObject;
        UnityEngine.Debug.Log("Attached Object: " + obj.name);
    }
}

Finally, if you have many scripts that you must access after instantiating the prefab then use var a = Instantiate(myPrefab) as GameObject;.

If you have one script or would like to modify just one script after instantiating the prefab as the "Bullet" example given above then use the shortcut from #2.

Programmer
  • 121,791
  • 22
  • 236
  • 328
0

you could see by your example that he's instantiating the Script itself and not all of the Gameobject, that way he can excute the methods without having the need to reference the script that excutes them. in other words if you don't need to instantiate the Gameobject itself for a specific reason then you should always instantiate the Script that could also hold a reference to the gameobject itself and manipulate it as you please

Ido Ben Shalom
  • 562
  • 4
  • 12