在 3.8.4 中,对 Node.setPosition/Rotation/WorldPosition 等一些接口(没有包括所有接口)的行为有些修改。
之前的逻辑是,不管传进来的值是否和当前值相等,无脑设置,包括触发后续的回调等操作。新的接口会判断传进来的值是否相等,如果相等,那么直接返回。
对于之前在引擎外部修改 Node.worldPosition/worldScale 等返回的 readonly 属性,然后再调用引擎设置接口,这种情况将不会触发数据脏标记,导致渲染画面不更新。
比如:
// 这里直接缓存 node.worldPosition 的值
let worldPos = this.node.worldPosition;
worldPos.x = 10;
// 这里会直接返回,导致修改失效。
//因为 worldPos 指向的就是 node 的 worldPosition,不管怎么改,setWorldPosition 在对比的时候,值都相等。
this.node.setWorldPosition(worldPos); //或者 this.node.worldPosition = worldPos;
注意:this.node.worldPosition = worldPos;
并非是引用赋值,而是走的 setter 流程,它的功能和 setWorldPosition 等效。 原型如下:
public set worldPosition(val:Readonly<Vec3>){
this.setWorldPosition(val);
}
正确的做法应该是:
//准备一个缓存变量
private _worldPos = v3();
this.node.getWorldPosition(this._worldPos);
this._worldPos.x = 10;
this.node.setWorldPosition(this._worldPos); //或者 this.node.worldPosition = this._worldPos;
又或者:
let worldPos = this.node.worldPosition;
this.node.setWorldPosition(worldPos.x + 10, worldPos.y, worldPos.z);
其它属性(scale, rotation, color 等) 同理。
在 update 中,建议不要使用 node.worldPosition.clone(); 这样的写法,会导致内存GC和性能问题。