跟踪 Component 的修改

栏目: Lua · 发布时间: 5年前

内容简介:在 ECS 框架中,每个 System 在每次更新时,都遍历一类 Component 依次处理。这对于游戏的大多数场景都适用,因为游戏引擎要处理的对象通常是易变的。对于每个对象单独判断是否应该处理反而有性能负担。但是,总有一些应用场景下,只对一类 Component 中的一小部分做修改,而没有被修改的对象可以保持上次的数据,而不必重复运算。在需要重算的对象数量远小于总量时,每个更新就很不划算了。为了减少运算量,我们通常的解决方案是增加一个脏标记,修改时设置,设置它。这样就可以在处理的时候只处理被标记过的对象

在 ECS 框架中,每个 System 在每次更新时,都遍历一类 Component 依次处理。这对于游戏的大多数场景都适用,因为游戏引擎要处理的对象通常是易变的。对于每个对象单独判断是否应该处理反而有性能负担。

但是,总有一些应用场景下,只对一类 Component 中的一小部分做修改,而没有被修改的对象可以保持上次的数据,而不必重复运算。在需要重算的对象数量远小于总量时,每个更新就很不划算了。

为了减少运算量,我们通常的解决方案是增加一个脏标记,修改时设置,设置它。这样就可以在处理的时候只处理被标记过的对象。常规的脏标记实现方案有两种,一是在 Component 上加一个 bool 字段,遍历的时候跳过没有标记的对象;二是在 Entity 上动态添加一个用于 tag 的 Component ,视作脏标记,遍历后再清除这个 tag 。

不过这两种方案在 lua 实现的 ecs 框架中,使用代价都比较大。

lua 和 C/C++ 不同,函数调用的成本相对比较大,为脏标记添加一个 set 方法不仅增加了运行成本而且也不符合 lua 的使用惯例(增加了使用成本)。我考虑用元方法来减少成本。

我们可以给需要跟踪的 Component 创建一个叫修改集 Modify 的结构,例如,如果要跟踪 transform 的修改,就创建一个 transform.modify 的修改集。这是一个特殊的有元方法的对象。对 transform.x 的修改,写作 transform.modify.x = newx 。这是一个更符合 lua 风格的用法。置脏的过程就隐藏在元方法里面。

modify 的实现依赖三张表。

  1. modify 对象本身,里面记录有关联的 entity id ,实际的数据区,元表。
  2. 持有修改后的数据的数据表。
  3. 元表,用来触发脏的行为。

工作起来是这样的,元表的 __index 关联到数据的数据表;元表先把 __newindex 关联在一个函数上,这个函数负责把 modify 关联的 entity id 添加到脏集合中,在第一次改写关联数据的时候触发。触发之后,修改 __newindex 元方法,直接引用和 __index 相同的数据表。

从第二次修改开始,就不再触发置脏的过程。元方法是有额外成本的,但 __index__newindex 关联到表而不是函数上,性能可以有极大的改善。

注意,读取 modify 结构本身是不触发置脏流程的。通常,业务逻辑只用关心老版本(上一帧)的 transform 状态;如果它必须关心当前帧是否有人修改 transform ,也可以主动查询 transform.modify 。

然后,我们提供 modify 集合的遍历方法,在一个独立的 system 中集中处理这一帧所有的修改集。在遍历之后,我们重置脏集合以及所有的 modify 的元表中的触发器。

我们实现这样一个机制的动机在于解决场景树的更新问题。场景树上的非叶节点的 transform 的修改会导致整个子树,另外,节点还有可能更换父亲,同样会导致整个子树的变化。

但是,整个场景的结构通常是稳定不变的,只有少量节点会经常更新自己的空间位置。我需要一个相对廉价的方案来决定场景树的哪一部分需要更新重算。

下一篇 blog 我将展开这个具体案例。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大型网站系统与Java中间件开发实践

大型网站系统与Java中间件开发实践

曾宪杰 / 电子工业出版社 / 2014-4-24 / 65.00

本书围绕大型网站和支撑大型网站架构的 Java 中间件的实践展开介绍。从分布式系统的知识切入,让读者对分布式系统有基本的了解;然后介绍大型网站随着数据量、访问量增长而发生的架构变迁;接着讲述构建 Java 中间件的相关知识;之后的几章都是根据笔者的经验来介绍支撑大型网站架构的 Java 中间件系统的设计和实践。希望读者通过本书可以了解大型网站架构变迁过程中的较为通用的问题和解法,并了解构建支撑大型......一起来看看 《大型网站系统与Java中间件开发实践》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

随机密码生成器
随机密码生成器

多种字符组合密码

html转js在线工具
html转js在线工具

html转js在线工具