在游戏子系统中注册游戏对象组件? (基于组件的游戏对象设计)
-
08-10-2019 - |
题
我正在创建一个 基于组件的游戏对象系统. 。一些技巧:
GameObject
只是一个清单Components
.- 有
GameSubsystems
. 。例如,渲染,物理等GameSubsystem
包含一些指针Components
.GameSubsystem
是一个非常有力和灵活的抽象:它代表游戏世界的任何切片(或方面)。
注册机制需要 Components
在 GameSubsystems
(什么时候 GameObject
是创建和组成的)。有 4种方法:
- 1: 责任链 图案。每一个
Component
提供给每个GameSubsystem
.GameSubsystem
做出决定Components
注册(以及如何组织它们)。例如,gameubsystemrender可以注册可渲染的组件。
Pro。 Components
对它们的使用方式一无所知。低耦合。 一个。 我们可以添加新 GameSubsystem
. 。例如,让我们添加gameubsystemtitles,以注册所有componentTitle,并确保每个标题都是唯一的,并通过标题为quering对象提供界面。当然,在这种情况下,不应重写或继承componentTitle。 B. 我们可以重组现有 GameSubsystems
. 。例如,可以将Gamesubsystemaudio,gameubsystemrender,gameubsystemparticlemmmiter合并到gamesubsystemspatial中(要放置所有音频,emmiter,渲染 Components
在相同的层次结构中,并使用父息转换)。
骗局。每次检查。非常无关。
骗局。 Subsystems
知道关于 Components
.
- 2:每个
Subsystem
搜索Components
特定类型。
Pro。比在 Approach 1
.
骗局。 Subsystems
仍然知道 Components
.
- 3:
Component
注册自己GameSubsystem(s)
. 。我们在编译时知道有一个gameubsystemrenderer,所以让我们的componentimagerender称为gameubsystemnerrenderer :: register(componentRenderbase*)之类的东西。
观察者 图案。Component
订阅“更新”事件(通过GameSubsystem(s)
).
Pro。表现。没有不必要的检查 Approach 1
和 Approach 2
.
骗局。 Components
与 GameSubsystems
.
- 4: 调解人 图案。
GameState
(其中包含GameSubsystems
)可以实现registerComponent(组件*)。
Pro。 Components
和 GameSubystems
彼此一无所知。
骗局。在C ++中,它看起来像丑陋和缓慢的类型开关。
问题:哪种方法更好,主要用于基于组件的设计?练习说什么?有关(数据驱动)实施的任何建议 Approach 4
?
谢谢你。
解决方案
投票给第三种方法。
我目前正在研究基于组件的游戏对象系统,并且清楚地看到了这种方法的其他优势:
该组件越来越多地自给自足,因为它仅取决于一组可用的子系统(我认为该集合已固定在您的项目中)。
数据驱动的设计更适用。理想情况下,您可以设计一个系统,其中组件按数据术语完全定义,而不是C ++。
编辑:我在CBGOS工作时考虑的一项功能。有时具有设计和构建能力很方便 子系统 被动组件。当您想到这一点时,第四种方法是唯一的方法。
其他提示
我的方法是在每个子系统中实现代理模式。由于每个子系统仅对每个实体可能包含的总组件的子集感兴趣,因此代理存储仅用于系统关心的组件,例如,运动系统仅关心位置和速度,因此它需要存储的代理来存储这些组件的两个指针。如果实体缺少其中一个或多个,则子系统将忽略它。如果两个组件都存在,则创建一个代理节点并添加到内部集合中。对于代理人存储实体的唯一标识符值也很有用,因此,如果有必要,可以从每个子系统中添加/删除代理。
以这种方式,如果需要从引擎中删除实体,则可以将包含实体ID的单个消息发送到每个子系统。然后可以独立从每个子系统集合中删除代理。