提问人:Michael Macha 提问时间:1/20/2022 更新时间:6/1/2023 访问量:730
当使用 new 创建 MonoBehaviour 时,究竟会发生什么?
What exactly happens when a MonoBehaviour is created with new?
问:
我知道这是“不允许的”;我无意中这样做了,它将从我的最终版本中彻底删除。显然,这条规则是有充分理由的。
奇怪的是,它位于单元测试组件中,尽管有警告,它仍然可以完美运行。我正在用继承自 MonoBehaviour 的类的几个构造实例填充列表,只是为了确保一个函数正在做我想让它做的事情,我收到了这个警告;但测试似乎运行良好。此外,这是一个警告,而不是真正的错误,这可能也是有原因的。
出于好奇,由于我的理解显然不完整,有人可以解释一下,如果可能的话,提供文档链接来解释为什么Unity不允许它显然能够做到的行为?为什么它禁止这样做,如果警告被忽略,会有什么缺点?
谢谢你完成我对它的理解。
答:
Unity 具有基于组件的体系结构。场景中存在的任何对象都由一个游戏对象表示,该游戏
对象附加了一个或多个对象。Component
组件经常更改它们所附加到的游戏对象的行为或外观。在某些情况下,组件还会相互引用或依赖。例如,组件倾向于串联使用。RigidBody
Collider
MonoBehaviour
脚本也派生自该类。您可以使用 创建行为对象,但它不会附加到任何游戏对象,因此不会在场景中正确存在。这可能会导致错误:Component
new
- 内置事件可能无法始终如一地工作。例如,、 、 或 。
Awake
Start
Update
OnCollisionEnter
- 内置引用根本不起作用。例如,、 或 和 函数系列。
gameObject
transform
AddComponent
GetComponent
- 其他组件以标准方式与此组件交互是不安全的。
- 场景转换可能会使问题复杂化,因为孤立的脚本不会附加到场景中的任何内容。
不过,您确实有一些其他选择。
您可以创建一个新的游戏对象,然后将脚本附加到该对象。这是用于管理整个场景(或跨多个场景)的游戏状态的脚本的常见工作流。这可能属于单例模式。
如果需要这些类在场景之外可用,也可以创建不派生自 的类。MonoBehaviour
评论
虽然这是一个古老的话题,但其中的一部分似乎仍未得到解决。
我有一个类似的问题 - 也许它会省去其他人的麻烦:警告是在运行完全没有引用MonoBehaviours的编辑器单元测试时发出的。这令人困惑。该警告似乎源自 NUnit.Framework 内部,并导致了一个不是我编写的脚本。
经过一番努力,我发现包含测试的类仍然继承自 MonoBehaviour(因为这是新脚本模板的一部分)。删除该继承解决了该问题。
评论
gameObject
Awake
Start
var component = new GameObject("some name"). AddComponent<YourComponent>();
MonoBehaviour
GameObject