可变数据
了解如何处理来自组件的只读和可变数据
当引用来自某个 组件时,你可以获取可变版本或只读(不可变)版本。
在可能的情况下,你应该始终处理数据的只读版本。与始终处理同一数据的可变版本相比,这种做法可以显著提升场景性能。
该 .get() 组件中的函数会返回该组件的只读(不可变)版本。你只能读取其值,不能更改其任何属性。
该 .getMutable() 函数会返回一个允许你更改其值的组件版本。只有当你计划修改组件时才使用可变版本,否则始终使用 get().
// 获取只读(不可变)版本
const immutableTransform = Transform.get(myEntity)
// 以下代码不会生效:
// immutableTransform.position.y = 2
const mutableTransform = Transform.getMutable(myEntity)
// 以下这行确实会更改实体的位置
mutableTransform.position.y = 2一个好的做法是遍历只读组件以检查其值,然后仅在需要更改时获取单个组件的可变版本。
// 硬编码的最大高度
const MAX_HEIGHT = 10
// 定义系统
function HeightLimitSystem(dt: number) {
// 遍历所有具有 Transform 组件的实体
for (const [entity] of engine.getEntitiesWith(Transform)) {
// 获取只读值
const currentHeight = Transform.get(entity).position.y
// 比较数值
if (currentHeight > MAX_HEIGHT) {
// 获取可变版本以进行更改
const mutableTransform = Transform.getMutable(entity)
// 更改变换
mutableTransform.position.y = MAX_HEIGHT
}
}
}
// 将系统添加到引擎
engine.addSystem(HeightLimitSystem)在上面的示例中,系统会检查实体的 Transform 组件的只读值。每一帧它都会检查位置的 y 是否高于硬编码的最大高度。如果变换中的高度确实高于此限制,那么并且只有在那时我们才获取 Transform 的可变版本。对于场景来说,这看起来可能像是额外的工作,但在一个我们在游戏循环的每一帧都检查数值、只在偶尔进行更改的场景中,它会带来巨大的性能提升。
这种做法遵循了 数据导向编程的原则。由于它带来的巨大改进,它也正逐渐被游戏行业采纳为一种行业标准实践。
📔 注意:在 SDK 的旧版本(6.x 或更早)中,组件始终被视为可变的。那种模式可能更容易学习一些,但运行效率要低得多。
最后更新于