Unity-使用组件作为界面

时间:2018-09-22 17:24:38

标签: c# unity3d inheritance interface

需要:

可以通过Component与附加在GameObject实例上的interface个实例进行交互。

例如,如果我与士兵一起玩游戏,并且假设医生和狙击手都是士兵,那么我希望能够将Soldier组件附加到士兵GameObject上,无论该士兵实际上是Sniper还是Medic。然后,我可以执行以下操作:soldier.GetComponent<Soldier>().Respawn();最终会根据士兵的实际类型来调用Medic.Respawn()Sniper.Respawn()

可能但肮脏的解决方案1:

第一个幼稚的方法是让SniperMedic组件实现Soldier interface。但是,这会导致一些问题。

例如,如果您想检查GameObject是否具有实现Soldier的组件,因为Soldier只是一个接口,而不是实际的Unity {{ 1}}。因此,在具有Component成分的GetComponent<Soldier>()上调用GameObject不会返回该Medic成分,即使Medic确实实现了{{1 }}。

(实际上,您可以通过遍历所有组件并使用Medic运算符来进行检查,但这会很脏而且很慢)。

可能但肮脏的解决方案2:

第二种方法是创建基础SoldierisComponentSoldier类将从中继承。

但这也带来了几个问题。

首先,仅在层次结构的叶类上调用Unity事件(MedicSniper等),从而迫使您手动在父类上调用相同的函数。任何尝试过的人都知道,忘记调用某些东西很容易,例如,这会导致对象初始化不正确。

第二,继承的常见问题也在这里。例如,如果我希望我的Awake()Start()的分量不仅是Medic,而且要是SniperSoldier或其他任何值,我就不能,因为C#不支持多重继承。

我正在考虑的方法:

我已经考虑过一种设计代码的方法,以解决上面列出的问题。

这个想法是要有一个Explodable类作为接口,并使该接口组件与同一个VehicleDriver上的acutal组件共存。换句话说,让两个游戏对象。其中一个将同时具有ComponentGameObject组件,而另一个将同时具有SoldierMedic组件。所有三个组件类,即SoldierSniperSoldier将完全分开,并且都从Medic继承。

代码的其他部分将仅与Sniper组件进行交互。在这种情况下,您可以执行:MonoBehaviour

然后,使用“接口”组件(即Soldier)来使用实际组件(即soldier.GetComponent<Soldier>().Respawn();Soldier)来执行特定操作将是可重复使用的

但是,由于Medic不了解SniperSoldier或将来可能添加的任何实现,因此Medic组件公开了实际的{{1 }} SniperSoldier必须实现。

由于可以实现多个接口,因此使用此解决方案可以使用多个“接口”组件。例如,一个士兵游戏对象可以具有以下“接口”组件:interfaceMedic,以及以下“实际”组件:Soldier,它将实现两个接口{{1} }和Soldier

您对此解决方案有何看法?谢谢!

编辑:

我编写了我的主意代码,它看起来很好用。我还创建了一个编辑器脚本,该脚本允许“接口”组件引用“实际”组件,而没有公共字段,而是使用属性。我将发布代码,以防万一有人想要它:

Explodable-水对象的“界面”组件:

Medic

RealWater.cs-实现“接口”组件的“实际”组件:

Soldier.ISolder

WaterComponentEditor.cs-自定义编辑器,不允许暴露裸域:

使用UnityEditor;

Explodable.IExplodable

可以随意重用,除非您发现此缺陷,在这种情况下,我真的很想知道!!

EDIT:该自定义编辑器的问题在于,即使“ {interface”组件未实现“ interface”组件公开的真实接口,您也可以使“ interface”组件引用任何WaterComponent.cs。仍然可以在自定义编辑器脚本中进行一些运行时检查,但这并不是那么干净。但是,我认为与该问题相比,优势仍然足够。

1 个答案:

答案 0 :(得分:1)

好吧...

  

GetComponent函数家族现在支持将接口用作通用参数。

Unity 5.0发行说明:https://unity3d.com/fr/unity/whats-new/unity-5.0

随便...