【问题标题】:How does Unity wiki's Singleton work?Unity wiki 的 Singleton 是如何工作的?
【发布时间】:2017-04-28 13:58:15
【问题描述】:

我的场景中有一个“管理器”游戏对象,并附加了一个 Manager 脚本组件。

我需要这个Manager 脚本是一个单身,因为有多个经理是没有意义的。

我使用了单例实现from the Unity wiki

我有两个问题:

  1. 为什么它会创建一个新的GameObject,然后使用GameObject.AddComponent<T>() 来实例化单例?为什么不直接new T()
  2. 我的SingletonManager 类构造函数都有protected。除了他们自己之外,没有人应该能够实例化这些类。 Unity 编辑器如何实例化它们?

【问题讨论】:

  • 您不能实例化派生自 Unity 内部 MonoBehaviour 类的对象。这就是new T() 不起作用的原因。
  • 我使用 Unity wiki 中的单例实现 - 将 您的代码 的相关部分添加到您的问题中会有所帮助
  • 请注意,您不应为继承自 MonoBehaviour 的类定义构造函数 - 请改用 Start()/Awake()/OnEnable() 方法。
  • 至于 Unity 编辑器如何将它们实例化?,大概是通过反射。即使一个类有privateprotected构造函数,你仍然可以使用反射找到构造函数和Invoke它。

标签: c# unity3d unity5


【解决方案1】:

正如 cmets 所说:

MonoBehaviour 类不能用 new T() 实例化,因为 GameObject 组件的工作方式:它们必须附加到 GameObject!因此,GameObject 类提供了一种实例化附加到该 GameObject 的新 MonoBehaviour 的方法:AddComponent<T>(),它可能通过反射进行操作(其他 MonoBehaviour 方法,例如 Start()Update()aren't exactly invoked with reflection,而不是运行时的每一帧,但是很容易将它们进行比较;它几乎是不透明和神奇的,并且有显着开销,所以它也可能是反射)。

完全阻止构造函数被调用可能只会破坏一切,所以不要费心试图保护它而不是你已经做的事情。由于 AddComponent 的工作方式,通过反射调用构造函数,您实际上无法阻止创建新实例,但您可以检测到它的发生并采取措施。我首选的方式是脚本运行“哦,一个实例已经存在,但它不是我”并自行销毁。

另外,由于组件可能需要其他组件(RigidBody 需要一个 Collider,MonoBehaviours can specify their own requirements 也是),这是通过属性指定的,当调用 AddComponent<T>() 添加一个组件时,它将搜索类属性到查看是否指定了任何 [RequireComponents] 并自动添加它们。这将完成through reflection

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 2018-03-08
    • 2018-12-17
    • 1970-01-01
    相关资源
    最近更新 更多