创建实体作为聚合


10

我最近询问了如何将实体与其行为分开以及与本文相关的主要答案:http : //cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

这里讨论的最终概念是:作为纯聚集体的对象。

我想知道如何使用C#将游戏实体创建为纯聚合。我还不太了解如何运行的概念。(也许实体是实现特定接口或基本类型的对象的数组?)

我当前的想法仍然涉及为每种实体类型都有一个具体的类,然后实现相关的接口(IMoveable,ICollectable,ISpeakable等)。

我如何才能完全将实体创建为聚合,而又没有该实体的任何具体类型?


如果您仍然有兴趣,我可以使用C#向您发送我的小型实体系统。这并不令人惊奇,但可以。
共产党鸭子

Answers:


6

West在该链接文章中描述的“纯聚合”方法完全避开了“实体”对象。有一些组件在内存中浮动,但是它们仅通过隐式关系(如果有的话)捆绑在一起。

一种实现方法是所谓的舷外方法。在这样的系统中,组件由管理或以其他方式控制它们的系统持有(我在这里使用术语“ manage”,但是您不应以此表示我建议您要持有一堆* Manager类。组件类型)。例如,您的物理系统可能会保留一堆代表模拟世界中每个刚体的事物,并将这些事物公开为PhysicsComponents。组件可以是所讨论的子系统处理的实际对象,也可以根据需要作为这些对象的代理。

在这样的系统中,不一定需要“实体”类来保存对构成它的组件的引用的集合。相反,会发出有关“实体”的创建或销毁的通知,并且处理组件的每个子系统都会查看已创建/已销毁实体的描述(通常从某些数据加载),并确定是否需要该组件。

这种方法的优点之一是,您可以获得每个组件的真正良好的引用局部性。不幸的是,这总体上有点怪异,而不是我遇到的基于组件的实体最友好的风格。有时,拥有一个代表实体的真实对象确实很方便,即使该对象所做的仅是多了一些,然后聚合对仍然由其他子系统持有的组件的弱引用(如果没有别的,它提供了一种在组件之间路由消息的简便方法) 。

有几种实现面向组件的游戏对象系统的好方法。如果您对系统中想要的需求有扎实的了解,那么它确实会非常有帮助-您可以查看像Unity这样的流行框架的示例。在没有为自己设置严格要求的情况下,您可能会遇到无休止地“设计”系统而不真正构建系统的问题,徒然地尝试实现完美的实现。无论出于何种原因,我在组件系统中都看到了很多。


3

Unity的方式是,所有脚本(在您的情况下,特定于某种游戏对象的游戏代码)都派生自基类MonoBehaviour,而基类本身又派生自与您的案例相关性更高的Component类。您永远不会编辑GameObject类(也无法访问其代码)。

游戏对象负责包含所有这些Component。从表面上讲,它还负责调用它们的相关功能(即Update)。Unity使用反射来确定要调用的函数(请参见本页上的“可覆盖的函数”部分),但是您可能希望将它们虚拟化。

因此,您在Unity中使用的一种机制是按类型获取当前游戏对象(或其子对象)上的组件。有一些帮助器属性包装了一些常见的东西。例如,如果您要访问游戏对象的Transform组件(以控制游戏对象的位置/旋转/比例),通常必须执行类似的操作this.GetComponent<Transform>().position,但它们会将其包装到帮助程序this.transform.position调用中。另一个常见的模式是访问当前游戏对象的Renderer组件。因此,如果您想执行诸如更改当前游戏对象的材质的操作,则可以从另一个脚本执行诸如的操作this.renderer.material = someOtherMaterial,并且您的游戏对象会适当更新。

在Unity中这种工作方式之一是设置他们的编辑器,以便您可以在场景中创建已经连接了组件的游戏对象。在Unity的情况下,所有游​​戏对象都有一个Transform组件,但是它也可以包含内置类型,例如AudioListenerRenderer,它们可以实现您所期望的。或者,您可以添加自己的组件,这些组件可以执行您希望它们执行的任何操作。该编辑器还在组件上公开了公共/可序列化的字段,因此,如果您要使用相同的基本代码,而无需更改其他脚本,则可以更改一些魔术数字。

总而言之,它非常漂亮,我建议下载免费版本的Unity并尝试如何设置其脚本系统,这是您想要实现的目标的相当不错的概念证明。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.