Unity - 组件类型和实例的混淆

Posted

技术标签:

【中文标题】Unity - 组件类型和实例的混淆【英文标题】:Unity - confusion over types and instances of components 【发布时间】:2020-10-07 06:34:11 【问题描述】:

我在这里有一个具体的问题,但其背后是我对数据类型以及 Unity 组件名称、标签和类型到底是什么的困惑。

具体问题是:我希望(在运行时,而不是通过编辑器)能够创建可以检测碰撞的组件并将检测信息传递给其他组件。组件非常简单 - 各种尺寸的(不可见)立方体,附有Colliders,并在每种情况下设置isTrigger。然后在碰撞检测(OnTriggerEntry()OnTriggerExit())上将碰撞信息传递给其他组件,例如“嗨,X 刚刚与数字 6 发生碰撞”。

最初我希望能够在假设它们是事件的情况下挂钩这些调用 - 但似乎它们不是事件(MonoBehaviour 覆盖,我假设)。在其他地方阅读,似乎唯一的方法是在创建组件后动态附加脚本(换句话说,一个 C# 类)。

由于会有许多这样的组件,它们都附加了相同的脚本(类),所以我需要设置一些内部类变量来告诉它在碰撞时要做什么/联系谁。这就是混乱开始的地方。

在我看来,Unity 设计人员/文档编制人员为了不给人们带来太多代码负担,往往会掩盖这些细节,或者至少试图以非软件方式解释它们。可以理解,但对于像我这样从软件角度思考的人来说非常困惑。

我附加的脚本中的类将有一个名称(例如,“MyCollisionHandler”),但这不是类的实例,它只是类定义 - 或类型,如果喜欢的话,例如'class MyCollisionHandler ...'。但是,一旦附加到组件上,就必须是这种情况(除非它只包含静态变量和函数),即存在它的实例。

所以,简单地说 - 我如何获得对附加到特定碰撞检测对象的通用类类型的特定实例的引用?一旦我有了它,我就可以使用方法以任何我喜欢的方式设置它。如果我使用FindObjectOfType<MyCollisionHandler>(),那将无济于事,因为可能有很多它们,它只会返回第一个找到的。好的,我可以改用 FindObjectsOfType<MyCollisionHandler>() 并获取它们的数组 - 但哪个是哪个?

所以,这又回到了我对 Unity 结构的普遍缺乏理解——组件名称、标签等之间的区别——以及它们与类定义和实例的关系。概括地说 - 如何获得附加到游戏对象的类对象的各个实例?

【问题讨论】:

【参考方案1】:

我附加的脚本中的类将有一个名字 (例如,'MyCollisionHandler'),但这不是 类

是的,实例由GameObject.AddComponent返回。

MyCollisionHandler handler = gameObject.AddComponent<MyCollisionHandler>();
handler.someValue = 42;

稍后您可以使用GameObject.GetComponent 获取实例,就像您为任何其他组件所做的那样。 如果您没有对脚本/组件附加到的游戏对象的引用,或者您不关心附加了此脚本/组件的游戏对象并且您只想要一个/全部,您将使用 FindObjectOfTypeFindObjectsOfType其中。

【讨论】:

好的,谢谢,所以类类型的实例由 AddComponent() 返回。因此,如果我使用 CreatePrimitive() 创建我的对象,继续使用该游戏对象引用,然后使用 AddComponent() 将类实例添加到它并继续使用返回的引用,我应该拥有一切。我注意到所有游戏对象都有唯一的实例 ID - 遗憾的是无法通过它进行搜索,尽管我认为可以在 Start() 时间遍历游戏对象树并保留记录。 @nmw01223 您也可以只保留使用 CreatePrimitive() 创建的所有游戏对象的列表,并使用 GetComponent() 获取脚本实例,或者保留从 AddComponent 返回的所有脚本实例的列表() 并从 MonoBehaviours gameObject 属性中获取它们所附加的游戏对象。

以上是关于Unity - 组件类型和实例的混淆的主要内容,如果未能解决你的问题,请参考以下文章

unity3d中间获取不在场景中的物体的组件

Unity3D研究院编辑器之不实例化Prefab获取删除更新组件(十五)

Unity IOC框架使用实例

Unity 动画系统 Animation 和 Animator的小实例

SIKI_Unity_2_入门_通过实例学习游戏的存档和读档

unity中怎样调用其他脚本变量