如何在实体组件系统中查找具有特定组件的实体?

时间:2014-09-18 20:03:41

标签: c++ game-engine

如何在实体组件系统中查找具有特定组件的实体?

在我目前的实施中,我将组件存储在一个中     std::unordered_map< entity_id, std::unordered_map<type_index, Component *> >

因此,如果系统需要访问具有特定组件的实体,那么访问它们的最有效方法是什么。

我目前有两个想法:

  1. 浏览地图并跳过没有这些组件的实体。
  2. 创建&#34;映射器&#34;或者&#34;观点&#34;持有指向实体的指针,并在每次将组件分配给实体或从实体中删除时更新它们。
  3. 我看到了一些使用bitmasks等的方法,但这看起来并不可扩展。

2 个答案:

答案 0 :(得分:1)

您的情况需要std :: unordered_multimap。

&#34;发现&#34; method将返回第一个元素的迭代器,该元素与multimap中的键匹配。 &#34; equal_range&#34;方法会返回一对,包含匹配键的第一个和最后一个对象的迭代器。

实际上,unordered_multimap允许你创建的是一个内存中的键值数据库,它为同一个键存储了一堆对象。

如果你的&#34;查询&#34;会比#34更复杂;给我所有带有组件T&#34的对象;变成像#34;给我所有同时包含组件T和B的组件&#34;,你更适合创建一个unordered_multimap作为成员的类,并且有一堆实用方法查询这些东西。

有关此主题的更多信息:

答案 1 :(得分:0)

我这样做的方法是从组件(32位)向实体存储一个反向索引。它增加了一点内存开销,但是我的组件的总内存开销大约是8个字节,这对我的用例来说通常不算太差,每个实体大约4个字节。

现在当你有一个实体的反向索引时,在满足具有2个或更多组件类型的所有实体的查询时你可以做的就是使用并行位集。

例如,如果您正在寻找具有两种组件类型MotionSprite的实体,那么我们首先迭代运动组件并为拥有的实体设置相关位它们。

接下来,我们遍历精灵组件并查找已通过运动组件设置的实体位。如果实体索引同时出现在运动组件和精灵组件中,那么我们将实体添加到包含两者的实体列表中。这个想法的图表以及如何多线程化并汇集实体并行位数组:

enter image description here

这为你提供了线性时间和非常小的m的交集(每次迭代非常非常便宜的工作,因为我们只是标记和检查一点 - 比一个更多,更多,更便宜哈希表,例如)。实际上,我可以使用这种技术在两秒内执行一组交集,每个集合中有1亿个元素。作为奖励,通过一些小的努力,如果您使用bitset来获取属于2个或更多组件的实体的索引,您可以使它按照排序顺序返回实体,以获得缓存友好的访问模式。

有很多方法可以比线性时间(Log(N)/Log(64))更好地实现这一点,尽管它实际上可以在一个毫秒内实现两个包含一亿个元素的集合之间的集合交集。这是一个提示:

enter image description here