把setSiblingIndex 当作zindex一样去用,但并不会生效,这个方法是干啥的?
试了试并不能达到效果,而 UITransform.prototype.priority才是想要的效果
但是在3.73 ‘UITransform.prototype.priority’ is deprecated.
?????????
是不是 3.73里的2D 元素和 3D元素一样使用Z来排序了?有大佬试过了吗
搜索一下吧.这个被质疑得很多.
3.7不知道重构了没有.
3.6以下设置这个值是原子的.不会对下一次排序有影响.
UITransform.prototype.priority这个方法看源码影响性能吧.
你不如自己看源码重新写一下.
很早以前做游戏的时候(别家引擎),为了实现 2D HUD 的遮挡顺序,我是这样实现的:
- 维护一个排序队列和一个 dirty 队列
- 使用 3D 对象距离摄像机的距离(有些游戏可以用 Y 坐标,或者像楼主一样自己设置的 zIndex,本质上是一样的)作为排序依据,排序依据改变时从排序队列移动到 dirty 队列
- 每隔 6 帧排序一次
- 排序时,判断 dirty 队列,长度相比排序队列比较短时,采用插入排序
- 长度比排序队列长很多时,合并数组并且使用快速排序
- 使用排序后的顺序刷新 UI 的 index buffer(相当于我们的 sibling index)
可以看出这里面的排序算法其实是非常自由的,不同的项目有各自可以采纳的优化空间。比如我每秒只需要刷新 10 次即可(肉眼一般看不出来),让引擎来实现的话每秒可能就要排序 60 次,性能还未必更好。
y 轴排序
大佬我写了个方案,一定时间全排一次,来应对大场景动态的Y轴排序
直接在引擎的node.ts添加如下方法
自定zIndex
然后在主逻辑的onload中这样写一个计时器,每一定时间对有排序需求的node进行排序
效果也达到了目的,性能开销也很小,看引擎的setSiblingIndex方法有状态通知之类的语句,没有一句句的研究,想请教大佬我这样写有没有什么问题
这个别家是u?
哇,最喜欢这种直接的方案,项目正好用到类似的内容,直接实现试试
我觉得没问题哈,性能开销是不大。如果调用得更频繁的话(比如调用 regularSiblingIndex 的对象非常多,不过一般游戏只会有一个),可以考虑缓存 .sort 传入的匿名函数。
可以問一下
Object.defineProperty(cc.Node.prototype, `zIndex`, {
set(zIndex) {
this._zIndex = zIndex;
if (this.parent && !Base.zIndexHandleMap.get(this.parent.uuid)) {
Base.zIndexHandleMap.set(this.parent.uuid, this.parent);
}
},
get() {
return this._zIndex || 0;
},
configurable: true
});
這段放在哪邊嗎? 想測試看看
任意位置新建js文件,头上写 import * as cc from
“cc”手机打的,格式化下
然后把这段放上就行了
base的话你在头上再写上 window.base = {}
类似的功能我做过,我的需求是每隔0.5秒把8个玩家按顺序放到最前面显示,因为只有8个节点,所以我直接把需要显示在上面的节点 setSiblingIndex (10)
不会优化的话在update里面每一帧调用就是了,也不费效率
function sortZ(parent: Node) {
const nodes = parent.children.slice();
// 条件自己看情况改, 在2d瓦片地图类型设定中, 通常y值就代表了z
nodes.sort((a, b) => b.position.y - a.position.y);
for (let i = 0, len = nodes.length; i < len; ++i) {
nodes[i].setSiblingIndex(i);
}
}
大佬,用你这个方法,在web上没问题,打包到Android就没用了,知道什么原因吗?引擎版本:3.8.3