这是一个类比:我有一个由细胞组成的有机体,这些细胞可以进一步由一系列附件组成。
我目前拥有的是一种子/父母之间的事件链来处理附加和分离组件(这可能会影响链上的任何东西),它根本不涉及 ecs,它们是实体中的函数。
现在我已经使用了事件组件(用于对象上的鼠标事件)。如果我希望系统是纯的,我会在附加组件等时创建附加组件吗?即便如此,我如何才能让所有必要的接收者进入使用该组件的系统?以这种方式而不是一系列功能来处理它是否值得?有没有更好的办法?
这是一个类比:我有一个由细胞组成的有机体,这些细胞可以进一步由一系列附件组成。
我目前拥有的是一种子/父母之间的事件链来处理附加和分离组件(这可能会影响链上的任何东西),它根本不涉及 ecs,它们是实体中的函数。
现在我已经使用了事件组件(用于对象上的鼠标事件)。如果我希望系统是纯的,我会在附加组件等时创建附加组件吗?即便如此,我如何才能让所有必要的接收者进入使用该组件的系统?以这种方式而不是一系列功能来处理它是否值得?有没有更好的办法?
免责声明:我不确定我是否正确地回答了您的问题。如果不是,我为谣言道歉。
为了处理 ECS 中的层次结构,您可以使用类似于以下内容的专用组件:
struct relationship {
entity_type first{entity_null};
entity_type prev{entity_null};
entity_type next{entity_null};
entity_type parent{entity_null};
// ... other data members ...
};
entity_type
您用于实体标识符的类型在哪里,这entity_null
是您的说法 -这还没有设置。这两件事主要取决于实际的实现。例如,在我自己的 ( EnTT
) 中存在entt::null
一种空实体,可在这种情况下使用。
现在让我们考虑层次结构中的一个通用节点: *parent
是父节点的实体标识符,以便您可以轻松地从叶子到根遍历树(A 层次结构)。*first
是第一个孩子的实体标识符,即当前标识符为根节点的子树的叶子或内部节点的列表。*prev
和next
是当前节点的兄弟姐妹的实体标识符。
当你想访问一个节点的所有子节点时,你从first
实体(它的第一个子节点)开始,通过访问一次一个地迭代它们,next
直到它变为空。当你想从一个节点返回到它的父节点时,你可以使用parent
.
该解决方案的一个优点是子列表是根据组件隐式定义的,您不必std::vector
为它们使用 an 或类似的。因此,您没有在组件中动态分配内存来创建层次结构。
如果你有兴趣,我也写了一篇关于这个主题的帖子。如果您想了解更多详细信息,可以阅读它。