注意:Node 的一些 set 接口行为的修正

这里的 set 不只是回调,还有别的一些逻辑。另外,如果对具体的接口设计有建议,建议可以开个新贴讨论。

明白了,感谢解答

这个问题很严重啊,还好逛论坛看到了。我很多项目的更新位置用getWorldPosition都不会再clone一次,一般都是node.getWorldPosition() 或者 node.worldPosition.clone()。

1赞

这个改动,老项目升级要全部代码都检查一遍了。

1赞

确实,+1

你们现在这么破坏兼容性 @wangzhe 没意见吗?

你们现在这么破坏兼容性 @wangzhe 没意见吗?
这么大的改动不用加到3.8.4的更新日志吗?

我顺着你的示例,写出这样的代码,这是能用的吗?

let worldPosition = node.getWorldPosition().clone();

worldPosition.x = 10;
node.setWorldPosition(worldPosition);

worldPosition.x = 20;
node.setWorldPosition(worldPosition);  // 此时会怎样?你的示例没覆盖这种 case

这么多年了瞎折腾的东西还少吗?

这是修复错误。另外,请你仔细看下 release note。

为了修复事件没有触发,导致对象必须 clone?否则值的更改不会生效。这叫修复错误?而且就这一句话,谁会想到兼容性被破坏呢?

这个说明似乎确实不是那么准确,但是这个改动我能理解,毕竟值没变,引起了变化,不利于性能优化,当然也可以单独判断对象的属性,不过可能这样改动就不是很通用了,我一般使用这些方法,都是传分量过去,基本不直接传对象

没看懂帖子的内容,帅哥可以总结一下吗?
看你这个描述,怎么好像getWorldPosition改成不会克隆了?

会导致节点点击事件无法响应, 坑的很

本来 getXXX 返回的就是只读属性,对这些属性的修改在原生也是没法起效的。在外部直接修改返回的只读属性,然后再调用 setXXX 接口设置不是很奇怪吗?

1赞

担心大家不清楚,所以我才特地建了这个帖子做更详细的说明。

建议把那个发布的说明点后面链接到这个帖子

嗯嗯,已经加了。

// 这里会直接返回,因为 worldPosition 指向的就是 node 的 world position
node.setWorldPosition(worldPosition);

没法理解这个修改意义何在? 谁会没事把一样的pos 调用set,大部分情况都是发生变化了才会调用。
除非引擎自己会大量调用node.setWorldPosition(worldPosition);并且,会传入同样的值。
那么为啥么引擎自己不做一个单独的方法 如:“__setWorldPosition(worldPosition); 或 setWorldPosition(worldPosition,isUpdate);”自己在引擎内部调用呢?给用户依然暴露旧的接口,这样既优化了,又对旧的版本兼容了。

首先,这还真不是引擎内部需要,是开发者反馈的 Node 的 setScale setPosition 等方法的性能问题 · Issue #16952 · cocos/cocos-engine · GitHub
另外,position 如果没有修改,但是又发出修改事件是错误行为。

这里唯一出问题的情况就是如果下使用

let pos = node.position;
pos.x += 1;  // 对 readonly 属性进行修改
node.position = pos; // 通过这个接口触发修改事件,因为只有 set 函数会通知修改事件

哦,正好借这个机会了讨论一下这属性的疑惑。
比如: 设计node.position 和 node.getPosition()的目的是啥?
例如:
let pos = node.postion;
pos.x += 1; // 1.希望node的坐标会被修改 2.希望只是修改pos,不修改node的坐标。

如果是“1.希望node的坐标会被修改 ” 那么
node.position = pos; //这个调用就不是必要的,就应该判断如果相等,就跳过。但是你要保证pos.x更改会触发node的逻辑
如果是“ 2.希望只是修改pos,不修改node的坐标”
let pos = node.postion; // 就应该获得一下clone的坐标点。

我感觉引擎设计这个的时候,有点乱啊。 还望林顺大佬解惑

getWorldPosition()返回的是一个新的对象,worldPosition的get方法返回的是Readonly。所以正常也是没问题的对吗?