我正在为游戏引擎开发实体组件系统。我的目标之一是使用面向数据的方法来优化数据处理。换句话说,我想遵循宁愿需要数组结构而不是结构数组的准则。但是,我的问题是我还没有找到一种巧妙的方法来为我解决这个问题。
到目前为止,我的想法是系统中的每个组件都负责游戏逻辑的特定部分,比如重力组件负责根据质量、速度等计算每一帧的力,而其他组件负责其他事情。因此,每个组件都对不同的数据集感兴趣。重力组件可能对质量和速度感兴趣,而碰撞组件可能对边界框和位置等感兴趣。
到目前为止,我认为我可以拥有一个数据管理器,它可以为每个属性保存一个数组。假设实体可能具有重量、位置、速度等中的一项或多项,并且它们将具有唯一的 ID。数据管理器中的数据将表示如下,其中每个数字代表一个实体 ID:
weightarray -> [0,1,2,3]
positionarray -> [0,1,2,3]
velocityarray -> [0,1,2,3]
如果所有实体都具有每个属性,则此方法效果很好。但是,如果只有实体 0 和 2 具有所有树属性,而其他实体是不移动类型的实体,它们将没有速度,数据将如下所示:
weightarray -> [0,1,2,3]
positionarray -> [0,1,2,3]
velocityarray -> [0,2] //either squash it like this
velocityarray -> [0 ,2 ] //or leave "empty gaps" to keep alignment
突然间,迭代它并不容易。如果我采用第二种方法,一个只对迭代和操纵速度感兴趣的组件将不得不以某种方式跳过空白间隙。保持数组短的第一种方法在更复杂的情况下也不能很好地工作。假设我有一个具有所有三个属性的实体 0,另一个只有重量和位置的实体 1,以及只有位置和速度的实体 2。最后,最后一个实体 3 只有权重。被压扁的数组看起来像:
weightarray -> [0,1,3]
positionarray -> [0,1,2]
velocityarray -> [0,2]
另一种方法会留下如下空白:
weightarray -> [0,1, ,3]
positionarray -> [0,1,2, ]
velocityarray -> [0, ,2, ]
如果您只对迭代只有少数属性的实体集感兴趣,那么这两种情况都不是简单的迭代。例如,给定的组件 X 会对处理具有位置和速度的实体感兴趣。如何提取可迭代数组指针以提供给该组件进行计算?我想给它一个数组,其中元素彼此相邻,但这似乎是不可能的。
我一直在考虑解决方案,例如为每个数组设置一个位字段,描述哪些点是有效的,哪些是间隙,或者一个系统将数据复制到没有孔的临时数组,然后将其提供给组件,以及其他想法,但我认为没有一个是优雅的,并且没有额外的处理开销(例如额外检查数据是否有效,或额外复制数据)。
我在这里问是因为我希望你们中的某些人可能有类似的经验,或者可能有有助于解决这个问题的想法或想法。:) 此外,如果这整个想法是废话并且不可能正确,而您有一个更好的想法,请告诉我。希望这个问题不会太长或太混乱。
谢谢。