【问题标题】:Unity3D /C# - What's the difference between instantiating a prefab as a GameObject vs a component class?Unity3D /C# - 将预制件实例化为游戏对象与组件类有什么区别?
【发布时间】:2017-05-30 23:49:54
【问题描述】:

假设我有一个名为 Bullet 的预制件,并附有一个名为 BulletControl.cs 的脚本。

我可以将其实例化为:GameObject bulletInstance = Instantiate(Bullet, transform); 或者我可以这样做:BulletControl bulletInstance = Instantiate(Bullet, transform);

我最初认为实例化为GameObject 只是一种更通用的类型,它可以让您访问其他参数,例如转换。据我了解,实例化不像使用new 关键字,所以我不认为当我声明bulletInstance 的类型时,我正在创建BulletControl 类的实例。这是怎么回事?

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    Instantiate 函数将Object 作为参数。

    在 Unity 中,每个 GameObject 和组件/脚本都直接或间接地继承自 Object

    假设您的脚本名称为YourScript

    YourScript 继承自 MonoBehaviour

    public class YourScript : MonoBehaviour
    {
    
    }
    

    那么MonoBehaviour继承自Behaviour

    public class MonoBehaviour : Behaviour
    {
    
    }
    

    Behaviour 继承自Component

    public class Behaviour : Component
    {
    
    }
    

    最后,Component 继承自 Object

    public class Component : Object
    {
    
    }
    

    对于GameObject,它直接继承自Object

    public sealed class GameObject : Object
    {
    
    }
    

    因此,任何从Object 继承的类都应该能够使用Instantiate 函数进行实例化。

    据我了解,实例化不像使用 new 关键字

    如果您的脚本不是从MonoBehaviour 继承的,那么您可以使用new 关键字来创建它的新实例,就像普通的C# 程序一样。如果它继承自MonoBehaviour,则必须使用InstantiateAddComponent 函数。请参阅this 帖子了解更多信息。

    【讨论】:

    • 另外,在添加许多组件时,实例化比通过代码创建更快。至少,我们所做的一项快速基准测试表明了这一点。可能是因为 Unity 提前知道预制件需要什么,它可能会优化流程。待确认。
    • “实例化比代码创建更快”你能解释一下你所说的代码创建是什么意思吗?
    • 当你有 GameObject obj = new GameObject("name", typeof(SomeType), typeof(SomeOtherType));然后你有一个已经附加类型的预制件,并且你使用了 Instantiate(prefab),我们注意到它在大规模上运行得更快。我们的情况是这样,但我不能对所有情况都适用,所以这就是我说要确认的原因。
    • 哦,我明白了。我还没有真正做过那个测试,但这可能是真的。您提到的第一种方法似乎是大量使用反射。另外,它将字符串作为游戏对象名称的参数。该字符串可能会导致内存分配,就像GameObject.tag一样。也许这就是原因。
    猜你喜欢
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    相关资源
    最近更新 更多