ECS和在游戏中的适当使用
ECS and appropriate usage in games
我一直在阅读实体组件系统,我想我理解基本概念:
实体只是 ID,其组件存储在数组中以减少缓存未命中。然后系统迭代一个或多个这些数组并处理组件中包含的数据。
但我不太明白这些系统应该如何高效、干净地相互交互。
1:如果我的实体有健康成分,我将如何破坏它?
如果生命值低于或等于 0,仅执行 health -= damage
不会解释死亡。但是向组件添加 damage()
函数将违背组件只是数据的观点。基本上:系统如何处理需要响应其更改并根据其更改更改其他组件的组件?(无需将损坏代码复制并粘贴到每个系统中,这可能会造成伤害)
2: 组件应该是没有函数的纯数据结构。我如何最好地处理特定于实体的行为,例如在死亡时爆炸。用像 explodesOnDeath=false
这样的内存浪费数据填充 Health 组件似乎是不切实际的,因为许多实体中只有一两个实际上会在死亡时爆炸。我不确定如何优雅地解决这个问题。
是否有解决这些问题的通用方法?
易于修改(例如使用 Lua 脚本)和高兼容性对我来说很重要,因为我真的很喜欢具有高改装潜力的游戏。 :)
使用语言:C++
我也是这个领域的新手,但以下是我在 ECS 模型方面的经验:
系统如何处理需要响应其变化的组件并根据其变化更改其他组件?
正如您正确指出的那样,组件只是数据的容器,因此不要赋予它们功能。所有的逻辑都由系统处理,每个新的逻辑片段都由不同的系统处理。所以把"dealing damage"和"killing an entity"的逻辑分开是个不错的选择。通讯
在 DamageSystem 和 DeathSystem 之间(换句话说,什么时候应该杀死一个实体)可以基于 HealthComponent .
可能的实现:
您通常有一个系统(DamageSystem)来计算实体的新生命值。为此,它可以使用关于实体的各种信息(组件)(也许你的实体有一些保护它们的盾牌,等等)。如果生命值低于 0,DamageSystem 不关心,因为它的唯一目的是包含造成伤害的逻辑。
除了 DamageSystem,你还想要某种 DeathSystem,它会检查每个实体的生命值是否低于 0 . 如果是这种情况,则采取一些行动。由于每个实体在死亡时都会做某事(这就是为什么你的 explodesOnDeath=false
不是一个坏主意的原因),所以有一个 DeathComponent 来存储某种枚举是很有用的对于死亡动画(例如爆炸或消失),声音文件的路径(例如奇特的爆炸声)和其他您需要的东西。
使用这种方法,所有的伤害计算都位于一个地方,并且与例如。一个实体死亡的逻辑。
希望对您有所帮助!
我一直在阅读实体组件系统,我想我理解基本概念:
实体只是 ID,其组件存储在数组中以减少缓存未命中。然后系统迭代一个或多个这些数组并处理组件中包含的数据。
但我不太明白这些系统应该如何高效、干净地相互交互。
1:如果我的实体有健康成分,我将如何破坏它?
如果生命值低于或等于 0,仅执行 health -= damage
不会解释死亡。但是向组件添加 damage()
函数将违背组件只是数据的观点。基本上:系统如何处理需要响应其更改并根据其更改更改其他组件的组件?(无需将损坏代码复制并粘贴到每个系统中,这可能会造成伤害)
2: 组件应该是没有函数的纯数据结构。我如何最好地处理特定于实体的行为,例如在死亡时爆炸。用像 explodesOnDeath=false
这样的内存浪费数据填充 Health 组件似乎是不切实际的,因为许多实体中只有一两个实际上会在死亡时爆炸。我不确定如何优雅地解决这个问题。
是否有解决这些问题的通用方法?
易于修改(例如使用 Lua 脚本)和高兼容性对我来说很重要,因为我真的很喜欢具有高改装潜力的游戏。 :)
使用语言:C++
我也是这个领域的新手,但以下是我在 ECS 模型方面的经验:
系统如何处理需要响应其变化的组件并根据其变化更改其他组件?
正如您正确指出的那样,组件只是数据的容器,因此不要赋予它们功能。所有的逻辑都由系统处理,每个新的逻辑片段都由不同的系统处理。所以把"dealing damage"和"killing an entity"的逻辑分开是个不错的选择。通讯 在 DamageSystem 和 DeathSystem 之间(换句话说,什么时候应该杀死一个实体)可以基于 HealthComponent .
可能的实现:
您通常有一个系统(DamageSystem)来计算实体的新生命值。为此,它可以使用关于实体的各种信息(组件)(也许你的实体有一些保护它们的盾牌,等等)。如果生命值低于 0,DamageSystem 不关心,因为它的唯一目的是包含造成伤害的逻辑。
除了 DamageSystem,你还想要某种 DeathSystem,它会检查每个实体的生命值是否低于 0 . 如果是这种情况,则采取一些行动。由于每个实体在死亡时都会做某事(这就是为什么你的 explodesOnDeath=false
不是一个坏主意的原因),所以有一个 DeathComponent 来存储某种枚举是很有用的对于死亡动画(例如爆炸或消失),声音文件的路径(例如奇特的爆炸声)和其他您需要的东西。
使用这种方法,所有的伤害计算都位于一个地方,并且与例如。一个实体死亡的逻辑。
希望对您有所帮助!