组件、行为和 MonoBehaviour 有啥区别?为啥这些是分开的?
Posted
技术标签:
【中文标题】组件、行为和 MonoBehaviour 有啥区别?为啥这些是分开的?【英文标题】:What is the difference between Component, Behaviour and MonoBehaviour? And why these are separated?组件、行为和 MonoBehaviour 有什么区别?为什么这些是分开的? 【发布时间】:2017-06-14 09:28:38 【问题描述】:MonoBehaviour 扩展了 Behavior 和 Behavior 扩展了 Component。 我想知道为什么这些类是分开的以及这些类的语义。 分离这些类有什么目的吗?有没有直接扩展 Behavior 或 Component 的类?
我知道我们必须使用 MonoBehaviour 在 Unity 中创建 C# 代码。 不过,我对 Unity 作为游戏引擎的架构很感兴趣。
【问题讨论】:
如果您不编写Start
ed 和Update
d 的代码,则无需继承MonoBehaviour
@DmitryPavlushin 嘿,这很有趣,如果我们不需要Start
或Update
,我们可以从 Behavior 或 Component 继承吗?我个人尽量避免使用这些(如果可能,我更喜欢事件驱动的代码),所以如果我们可以继承这些,那会是更好的做法吗?
@DmitryPavlushin 听起来像是一个答案。
举个例子,您可能有一个预制件,例如包含有关 MB 脚本上预制件的数据。通过预制创建新实例时,您可以访问这些数据并在其上运行一些方法。您可以通过 GetComponent 访问脚本。经常在游戏中你需要访问这些数据,因为假设你的物品是一个会破坏其他物品的弹丸。该脚本可能没有任何开始或更新。因此,第一条评论是错误的。
【参考方案1】:
组件:
Component
是Behaviour
和MonoBehaviour
的基类。它是可以附加到游戏对象的任何脚本的基类。
这几乎是每个 Unity 内置 脚本的来源。这包括Collider
和Rigidbody
。
行为:
关于Behaviour
,最重要的一点是可以启用或禁用从它继承的任何东西。如果您不想启用/禁用它,请不要继承您的脚本。
例如,Rigidbody
无法启用/禁用。这就是为什么它继承自 Component
类而不是 Behaviour
。
Behaviour
继承自 Component
。
单一行为:
关于MonoBehaviour
,最需要注意的是,当你必须使用协程、调用或任何 Unity 回调函数(如物理OnCollisionEnter
函数、Start
、OnEnable
、@987654337)时,你需要它@等
MonoBehaviour
继承自 Behaviour
,因此可以启用/禁用您的脚本。
分离这些类有什么目的吗?
是的,就像上面的答案一样,它们是分开的,因此您可以通过从适当的组件继承来使用不同的功能。
您想要协同程序Invoke
、InvokeRepeating
并能够启用/禁用您的脚本?使用继承自MonoBehaviour
。
您希望能够启用或禁用脚本但不需要协程Invoke
、InvokeRepeating
?使用Behaviour
。
当您有一个永远不应启用/禁用的脚本时,它应该继承自 Component
。
请注意,Behaviour
和 Component
被 Unity 用于内部内容。你不应该尝试从这些继承你的脚本。
将它们分开的主要原因是为了节省内存,同时也使每个组件中的代码易于维护。这比为一个很少使用的功能编写数千行代码要好。通过分离它们,当它们被加载到内存中时,它们实际上正在被使用,而不是浪费内存中的空间。
有没有直接扩展 Behavior 或 Component 的类?
是的。
MonoBehaviour
直接继承自 Behaviour
然后
继承自Component
。
Collider
直接继承自 Component
。然后是非基础对撞机
比如BoxCollider
和SphereCollider
继承自Collider
。
【讨论】:
@Programmer “是的,它占用了这么多内存,只有在加载下一个场景时才会释放。”你确定吗?它将一直保留到帧结束,然后将其标记为 GC。如果需要场景加载来清理被破坏的对象,这将是设计的主要缺点。还是您的意思不同? @kyasbal 可能是由于底层 Mono 框架的历史原因。就像所有 Objective-C 类在 NextStep 时都以 NS 开头一样。那么在没有害处的情况下删除前缀就太复杂了。 "注意,行为和组件被 Unity 用于内部的东西。你不应该尝试从这些继承你的脚本。"这与你所说的其他一切相矛盾。当我读到这句话时,听起来你说永远不要从 Behavior 或 Component 继承。是这个意思吗? 我知道这很令人困惑,但是当我说“你”时,我并不是指像你这样的普通程序员。我主要指的是为 Unity 工作的程序员。我还指的是为Unity's UI system 做出贡献的程序员,这是开源的。您将必须了解这些是如何工作的,为什么要使用它们以及何时使用它们中的任何一个才能做出贡献。如果您不是这些人中的任何一个,则不需要使用其中任何一个。 不,您不必将其存储为组件。一旦您在从 MonoBehaviour 创建的另一个类中声明该数据类,您将在 Editor/Inspector 中看到该数据类及其所有变量。它们必须被声明为公共的,或者如果是私有的,则必须具有[SerializeField]
。以上是关于组件、行为和 MonoBehaviour 有啥区别?为啥这些是分开的?的主要内容,如果未能解决你的问题,请参考以下文章