繁体   English   中英

Unity,实例化一个需要特定脚本的预制件

[英]Unity, Instantiate a prefab requiring it to have a specific script

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

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

然后,如果myPrefab具有脚本MyScript,则可以访问其方法或变量,如下所示:

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

在第5章的“行动中的团结”一书中,作者使用了不同的方法:

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

据我了解,通过这种方式,我可以使用较短的sintax访问脚本的变量和方法,但是需要较长的sintax来访问包含的GameObject。 (我认为是这样的:a.GetComponentInParent())

除了本书以外,我没有找到关于这种实例化对象的方法的文档,我想听听对此的看法。

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

  • 场景中的每个Prefab或Object都有一个GameObjectTransform
  • 每个脚本/组件或GameObject都继承自Object 因此,您可以实例化任何脚本/组件或GameObject。 刚刚在这几个小时前回答过,因此请参阅帖子以获取完整说明。

为了回答您的问题,他们俩都在做同样的事情。 如果您将组件/脚本传递给Instantiate函数,则Unity将获取每个脚本/组件以及与该脚本相连的GameObject,然后实例化它们。

如何决定使用哪个示例:

假设您有一个名为“子弹”GameObject预制件,并且该子弹带有一个固定的Rigidbody 您要实例化项目符号,然后按AddForce到项目符号...。

您有两种选择:

1 .Instantiate子弹作为游戏对象然后拿到Rigidbody从它GetComponent这样你就可以添加力到它:

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子弹作为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;

如果您有一个脚本,或者想在将预制实例化为上面给出的“ Bullet”示例后仅修改一个脚本,请使用#2的快捷方式。

通过示例可以看到,他实例化了脚本本身,而不是实例化所有Gameobject,这样他就可以执行方法,而无需引用执行它们的脚本。 换句话说,如果您不需要出于特定原因实例化Gameobject本身,则应始终实例化脚本,该脚本还可以保留对Gameobject本身的引用并根据需要进行操作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM