需要:
可以通过Component
与附加在GameObject
实例上的interface
个实例进行交互。
例如,如果我与士兵一起玩游戏,并且假设医生和狙击手都是士兵,那么我希望能够将Soldier
组件附加到士兵GameObject
上,无论该士兵实际上是Sniper
还是Medic
。然后,我可以执行以下操作:soldier.GetComponent<Soldier>().Respawn();
最终会根据士兵的实际类型来调用Medic.Respawn()
或Sniper.Respawn()
。
可能但肮脏的解决方案1:
第一个幼稚的方法是让Sniper
和Medic
组件实现Soldier
interface
。但是,这会导致一些问题。
例如,如果您想检查GameObject
是否具有实现Soldier
的组件,因为Soldier
只是一个接口,而不是实际的Unity {{ 1}}。因此,在具有Component
成分的GetComponent<Soldier>()
上调用GameObject
不会返回该Medic
成分,即使Medic
确实实现了{{1 }}。
(实际上,您可以通过遍历所有组件并使用Medic
运算符来进行检查,但这会很脏而且很慢)。
可能但肮脏的解决方案2:
第二种方法是创建基础Soldier
类is
,Component
和Soldier
类将从中继承。
但这也带来了几个问题。
首先,仅在层次结构的叶类上调用Unity事件(Medic
,Sniper
等),从而迫使您手动在父类上调用相同的函数。任何尝试过的人都知道,忘记调用某些东西很容易,例如,这会导致对象初始化不正确。
第二,继承的常见问题也在这里。例如,如果我希望我的Awake()
和Start()
的分量不仅是Medic
,而且要是Sniper
或Soldier
或其他任何值,我就不能,因为C#不支持多重继承。
我正在考虑的方法:
我已经考虑过一种设计代码的方法,以解决上面列出的问题。
这个想法是要有一个Explodable
类作为接口,并使该接口组件与同一个VehicleDriver
上的acutal组件共存。换句话说,让两个游戏对象。其中一个将同时具有Component
和GameObject
组件,而另一个将同时具有Soldier
和Medic
组件。所有三个组件类,即Soldier
,Sniper
和Soldier
将完全分开,并且都从Medic
继承。
代码的其他部分将仅与Sniper
组件进行交互。在这种情况下,您可以执行:MonoBehaviour
。
然后,使用“接口”组件(即Soldier
)来使用实际组件(即soldier.GetComponent<Soldier>().Respawn();
或Soldier
)来执行特定操作将是可重复使用的
但是,由于Medic
不了解Sniper
,Soldier
或将来可能添加的任何实现,因此Medic
组件公开了实际的{{1 }} Sniper
和Soldier
必须实现。
由于可以实现多个接口,因此使用此解决方案可以使用多个“接口”组件。例如,一个士兵游戏对象可以具有以下“接口”组件:interface
和Medic
,以及以下“实际”组件:Soldier
,它将实现两个接口{{1} }和Soldier
。
您对此解决方案有何看法?谢谢!
我编写了我的主意代码,它看起来很好用。我还创建了一个编辑器脚本,该脚本允许“接口”组件引用“实际”组件,而没有公共字段,而是使用属性。我将发布代码,以防万一有人想要它:
Explodable
-水对象的“界面”组件:
Medic
RealWater.cs-实现“接口”组件的“实际”组件:
Soldier.ISolder
WaterComponentEditor.cs-自定义编辑器,不允许暴露裸域:
使用UnityEditor;
Explodable.IExplodable
可以随意重用,除非您发现此缺陷,在这种情况下,我真的很想知道!!
EDIT:该自定义编辑器的问题在于,即使“ {interface”组件未实现“ interface”组件公开的真实接口,您也可以使“ interface”组件引用任何WaterComponent.cs
。仍然可以在自定义编辑器脚本中进行一些运行时检查,但这并不是那么干净。但是,我认为与该问题相比,优势仍然足够。
答案 0 :(得分:1)
好吧...
GetComponent函数家族现在支持将接口用作通用参数。
Unity 5.0发行说明:https://unity3d.com/fr/unity/whats-new/unity-5.0
随便...