团结,实例化预制,要求它具有特定的脚本



当我想实例化prefab时,我会做这样的事情:

[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(((

我还没有找到有关这种实例化对象的方式的文档,我想听听对此的意见。

在阅读此答案之前要理解的东西:

  • 场景中的每个预制或对象都有GameObject,并且 Transform
  • 每个脚本/组件或GameObject从Object继承。因此,您可以实例化任何脚本/组件或游戏对象。刚刚回答了几个小时,所以请参阅这篇文章用于完整的解释。

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

如何决定使用哪个示例:

假设您有一个称为" bullet" GameObject预制,并且该子弹在其上附有Rigidbody。您想在钥匙件上实例化子弹,然后 AddForce到子弹..

您有两个选择:

1 。以GAMEBJJECT为"子弹",然后使用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 。以RigidbodyAddForce的子弹。

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函数的通用版本来简化A-lot代码:

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(((

就像我的第二个评论一样,每个脚本都有一个游戏对象。您需要做的就是scriptName.gameObject获取该脚本的GameObject,而scriptName.transform获得该GameObject的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;

如果您有一个脚本,或者想在实例化预制作为上面给出的"子弹"示例后仅修改一个脚本,则使用#2

您可以通过示例看到他正在实例化脚本本身,而不是所有的游戏对象,这样他就可以在不需要引用对其的脚本的情况下进行勾选。换句话说,如果您不需要出于特定原因实例化游戏对象本身,则应始终实例化脚本,该脚本也可以包含对GameObject本身的引用并按照您的操作进行操作

最新更新