如何处理 ECS 中的动态层次实体

How to handle dynamic hierarchical entities in ECS

打个比方:我有一个有机体,它由细胞组成,而细胞又可以进一步由多种附件组成。

我目前拥有的是 child/parents 之间的一种事件链,用于处理附加和分离组件(这可能会影响链中的任何东西),它根本不涉及 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 是 parent 节点的实体标识符,这样你就可以轻松地从叶子到根遍历树(A hierarchy)。 * first是第一个children的实体标识符,即当前标识符为根节点的子树的叶子或内部节点列表。 * prevnext 是当前节点的兄弟实体标识符。

当你想访问一个节点的所有children时,你从first实体开始(它的第一个child ) 并通过访问 next 一次迭代一个,直到它变为空。当你想从一个节点回到它的 parent 时,你可以只使用 parent.

此解决方案的 plus 是 children 的列表是根据组件隐式定义的,您不必使用 std::vector 或类似的。因此,您没有在组件中动态分配内存来创建层次结构。

如果您有兴趣,我还写了一篇关于这个主题的 post。如果你想了解更多细节,你可以阅读它。