-
Creator 版本: 3.6.0
-
目标平台: iOS / Android / 模拟器
-
重现方式:多个2D显示对象,3.5版本使用node.children.sort排序后,显示对象的渲染顺序正常,在3.6.0版本中,web端正常,真机上就无效了.
-
重现概率: 100%
具体代码发一下
这是在3.6.0版本下的测试代码.
正常情况下,3盖住2盖住1
在web端运行没有问题,cc里用模拟器运行,就无效了
assets.zip (118.4 KB)
这是模拟器上的效果:
这是在浏览器里运行的效果:
请问这个问题在修复中了吗?这个问题对于我的项目来说,非常非常重要…
3.6 中,Node 已经在原生上实现了。ts 的 children 和 c++ 的 children 需要同步操作。
理论上不应该直接在 ts 中拿 children 去做 sort 的操作,可能 Node 需要提供类似的 sortChildren 的API给开发使用会更合理点。
当前临时处理的话,可以尝试一下,在 this.node.children.sort 之后调用一下 this.node._setChildren 私有接口进行强行同步下 children 到 c++ 层中。
if (this.node._setChildren) {
this.node._setChildren(this.node.children);
}
if ((this.node as any)._setChildren) {
(this.node as any)._setChildren(this.node.children);
}
先是取消了对节点设置zIndex后自动排序
现在children也不给排序
你们干这些事情的时候,没有讨论一下的么
产品经理不参加review,不盯一下工作计划的么 @jare
感觉3.x以来,你们团队就变得乱糟糟,是人太多管理不过来了么
原生化之后,所有绑定对象的 Pure JS Array 和 Object 类型的属性,都不允许直接修改内部量,这是 JS 特性导致的无法做到的结果。
对于 Node 来说,属性是 children
,它的类型是数组,要改变这个属性的内容,必须重新进行赋值,这样原生侧才有可能得到通知,如果直接修改 JS Array 本身,C++ 是不可能得到通知,也不知道这个属性的改变。除了 children
以外,position
不允许直接对分量进行修改 position.x = 0
也是一样的原因。
这些问题不可避免,我们也尝试过通过 Object.freeze API protect 属性,参考我这个 PR,但是由于 loose 模式下实际上不会得到任何通知,所以其实没有任何保护效果。而且 freeze 会带来额外的性能开销,所以放弃了。
原生化过程中,请注意,只能使用引擎公开 API,下面这类的用法都是错误的
node.children.splice(0, 1);
node.children.sort(callback);
node.position.x = 0;
component.color.r = 255;
可以参考文档 开发注意事项 · Cocos Creator
- 定制引擎, 加上上面大佬说的代码(2d显示排序的老方法再坚持坚持
)
private static _sortChildrenSibling (node) {
const siblings = node.children;
if (siblings) {
siblings.sort((a:Node, b:Node) => {
...
});
// https://forum.cocos.org/t/topic/138996/6
if ((node as any)._setChildren) {
(node as any)._setChildren(siblings);
}
}
}