【问题标题】:Begginer in entity component system实体组件系统初学者
【发布时间】:2020-10-18 01:49:16
【问题描述】:
我刚刚深入研究了实体组件系统并喜欢这个想法。我已经了解它背后的基础知识,但细节是大多数问题隐藏的地方。所以我想知道是否有人可以帮助我克服它?
-
实体-组件结构应该是什么?我已经看到了两种实现方式 - 将实体作为对象/结构并在内部作为变量。其次,具有组件的数组或映射,其中数组或 int 在映射中的索引表示实体的 ID。哪种方式更好?
-
如果将实体作为合法对象的第一种方法更好,那么我应该如何找到具有系统特定组件的实体?我是否应该遍历每个实体,然后遍历它的组件数组以查明它是否具有此特定组件?相同的逻辑可以应用于不同组件的映射,因为我需要再次循环遍历映射以查找它是否具有特定的 id。
-
如果使用数组的第二种方法为真,那么如果我有一个像“PlayerController”这样的组件,它只分配给一个实体,但仍然会有这些组件的整个数组(只是空值,但它们也占用 64位)。以防万一-我需要整个数组作为数组中项目的索引实际上代表实体的 id 所以我需要数组至少是具有该组件的实体的 id 的大小,但也可能是比泛化要大
奇怪的是,如此漂亮的架构在网上没有太多信息,只有图书馆(和那些教程),如果你想了解其中的深度,你必须查看它们。
【问题讨论】:
标签:
entity-component-system
【解决方案1】:
对于数据类型 - Dicts/Tables/Structs 是最好的。对象确实会妨碍您,因为您可能很想将可能是系统级功能的东西变成辅助功能。以后可能会回来咬你。要使用表格构建实体,有一个概念是使用 Assemblages/Archetypes 将实体轻松拼接在一起。
存储方法很大程度上取决于您的语言。如果它可以从数据存储在连续内存块中的缓存优化中受益,那就很重要了。然而,对于 C++/Java 和使用“魔术”指针构建的语言,它们不会从缓存优化中受益(我使用 Lua,这只是人们在 reddit 上告诉我的)。这些表本身是连续的,但不一定彼此连续。所以没关系。
如果您可以控制内存分配,那么您必须权衡单一的利弊 -
-
集中式实体存储需要较少的开销来查找组件,因为它们位于同一个实体表中。但是,每个系统的循环都需要以if component == true 语句开始,以确定它是应该对实体进行操作还是跳过它。不过如果是便宜的话。
-
去中心化实体存储不需要 if 检查,因此系统不会浪费时间检查不需要他们注意的实体。但是,更新其他阵列中的(共同)相关组件会产生额外的开销,因为系统必须潜在地搜索更长的时间才能找到它需要的东西。这种开销会随着更多依赖项的增加而增加,因此使组件尽可能独立是最佳实践(但并不容易)。您可以通过将相互依赖的组件转换为更大组件(即表格)的子组件来解决这个问题。
无论哪种方式,您都必须分析您的代码。如果大多数实体具有大多数组件,则集中式方法会更好。对于组件差异很大的实体,去中心化方法更加灵活。最终,选择你更喜欢的。
要回答您的第三个要点(如果我理解的话),您只将有用的信息存储在去中心化模型中。假设你有一个玩家和 19 个敌人,玩家有一个“玩家输入”组件。 Player 将被输入到 Player-Input 组件表中,Player-Input 系统将查看具有 one 播放器条目的 one 组件表以传递它的输入。你不需要 19 个空值,这违背了去中心化的意义。或者,您可以制作一个同时处理控制器输入和 AI 输入的“输入”系统,但两者可以是单独的系统。这取决于你。