Unity,实例化一个预制件,要求它具有特定的脚本

时间:2017-05-31 22:33:59

标签: c# unity3d

当我想要实例化预制件时,我会做这样的事情:

Database::$db->exec

然后,如果myPrefab有一个脚本MyScript,我可以像这样访问它的方法或变量:

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

在书" Unity in Action"在第5章中,作者使用了不同的方法:

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

据我了解,通过这种方式,我有一个更短的sintax来访问脚本的变量和方法,但我需要更长的sintax来访问包含GameObject。 (我认为这样的事情:a.GetComponentInParent())

除了本书之外,我还没有找到关于这种实例化对象的方法的文档,我想听听有关这方面的意见。

2 个答案:

答案 0 :(得分:4)

在阅读本答案之前需要了解的事项:

  • 场景中的每个预制件或对象都有一个GameObjectTransform
  • 每个脚本/组件或GameObject都继承自Object。 因此,您可以实例化任何脚本/组件或 游戏对象。刚刚在几个小时前回答,请看this帖子 有一个完整的解释。

要回答你的问题,他们俩都在做同样的事情。如果您将组件/脚本传递给Instantiate函数,Unity将获取附加到该脚本的每个脚本/组件和GameObject,然后实例化它们。

如何决定使用哪一个的示例:

让我们假设你有一个名为&#34; bullet&#34; GameObject预制件,并且该子弹附有Rigidbody。您希望在按键时将子弹实例化,然后AddForce到子弹....

您有两种选择:

1 。将子弹作为GameObject进行实例化,然后使用GetComponent从中获取Rigidbody,以便您可以为其添加力:

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 。将项目符号设为Rigidbody,然后AddForce为其。

public Rigidbody myPrefab;

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

使用此版本是有道理的,因为没有使用GetComponent。如果您只需要访问组件,那么只需使用此方法。

在最新版本的Unity中,通过添加Instantiate函数的通用版本已经简化了这一过程,因此您甚至不需要将其强制转换为脚本或对象类型,从而减少把整个事情写成一行代码:

public Rigidbody myPrefab;

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

但我需要更长的sintax来访问包含GameObject。 (一世   想这样的事:a.GetComponentInParent())

就像我的第二条评论一样,每个脚本都有一个GameObject。您只需scriptName.gameObject获取该脚本的GameObject,然后scriptName.transform获取该游戏对象的Transform

例如:

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);
    }
}

最后,如果您在实例化预制件后必须访问许多脚本,请使用var a = Instantiate(myPrefab) as GameObject;

如果您有一个脚本,或者想要在将预制件实例化为&#34; Bullet&#34;之后只想修改一个脚本。上面给出的示例然后使用#2

中的快捷方式

答案 1 :(得分:0)

你可以通过你的例子看到他正在实例化脚本本身而不是所有的Gameobject,这样他就可以执行这些方法,而无需引用那些可以使用它们的脚本。换句话说,如果您不需要为特定原因实例化Gameobject本身,那么您应该始终实例化脚本,该脚本也可以保存对游戏对象本身的引用并随意操纵它