88 lines
3.5 KiB
TypeScript
88 lines
3.5 KiB
TypeScript
/**
|
|
* UI 的渲染在 v3.0 变为使用 node.layer 来判断可见性,为了保证老版本项目升级后表现一致,
|
|
* Creator 会在运行时动态分配一个未使用的 layer 给常驻节点的 UI,避免常驻节点的 UI 与场景中
|
|
* 的其他 UI 的 layer 发生冲突,当你确定不会发生冲突时,你可以移除此脚本.
|
|
*
|
|
* UI rendering has changed in v3.0 to use node.layer to determine visibility.
|
|
* To ensure consistent performance after upgrading old projects.
|
|
* Creator will dynamically assign an unused layer to the UI node in the persist node at
|
|
* runtime to avoid conflicts between the layer of UI in the persist node and the
|
|
* layer of other UI in the scene. You can remove this script when you
|
|
* are sure there is no conflict
|
|
*/
|
|
|
|
import { _decorator, Node, director, Director, game, BaseNode, Canvas, Camera } from 'cc';
|
|
import { EDITOR } from 'cc/env';
|
|
|
|
const customLayerMask = 0x000fffff;
|
|
const builtinLayerMask = 0xfff00000;
|
|
|
|
director.on(Director.EVENT_AFTER_SCENE_LAUNCH, () => {
|
|
const roots = director.getScene()?.children as BaseNode[];
|
|
let allCanvases = director.getScene()?.getComponentsInChildren(Canvas) as Canvas[];
|
|
if (allCanvases.length <= 1) return;
|
|
allCanvases = allCanvases.filter(x => !!x.cameraComponent);
|
|
|
|
let allCameras = director.getScene()?.getComponentsInChildren(Camera) as Camera[];
|
|
let usedLayer = 0;
|
|
allCameras.forEach(x => usedLayer |= (x.visibility & customLayerMask));
|
|
|
|
const persistCanvas: Canvas[] = [];
|
|
for (let i = 0, l = roots.length; i < l; i++) {
|
|
const root = roots[i];
|
|
if (!game.isPersistRootNode(root)) continue;
|
|
const canvases = root.getComponentsInChildren(Canvas);
|
|
if (canvases.length === 0) continue;
|
|
persistCanvas.push(...canvases.filter(x => !!x.cameraComponent));
|
|
}
|
|
|
|
persistCanvas.forEach((val) => {
|
|
const isLayerCollided = allCanvases.find(x => x !== val && (x.cameraComponent!.visibility & val.cameraComponent!.visibility & customLayerMask));
|
|
if (isLayerCollided) {
|
|
const availableLayers = ~usedLayer;
|
|
const lastAvailableLayer = availableLayers & ~(availableLayers - 1);
|
|
val.cameraComponent!.visibility = lastAvailableLayer | (val.cameraComponent!.visibility & builtinLayerMask);
|
|
setChildrenLayer(val.node, lastAvailableLayer);
|
|
usedLayer |= availableLayers;
|
|
}
|
|
});
|
|
});
|
|
|
|
function setChildrenLayer (node: Node, layer: number) {
|
|
for (let i = 0, l = node.children.length; i < l; i++) {
|
|
node.children[i].layer = layer;
|
|
setChildrenLayer(node.children[i], layer);
|
|
}
|
|
}
|
|
|
|
let setParentEngine = Node.prototype.setParent;
|
|
|
|
if(!EDITOR) {
|
|
Node.prototype.setParent = function(value, keepWorldTransform) {
|
|
setParentEngine.call(this, value, keepWorldTransform);
|
|
if (!value) return;
|
|
// find canvas
|
|
let layer = getCanvasCameraLayer(this);
|
|
if (layer) {
|
|
this.layer = layer;
|
|
setChildrenLayer(this, layer);
|
|
}
|
|
}
|
|
}
|
|
|
|
function getCanvasCameraLayer (node: Node) {
|
|
let layer = 0;
|
|
let canvas = node.getComponent(Canvas);
|
|
if (canvas && canvas.cameraComponent) {
|
|
if (canvas.cameraComponent.visibility & canvas.node.layer) {
|
|
layer = canvas.node.layer;
|
|
} else {
|
|
layer = canvas.cameraComponent.visibility & ~(canvas.cameraComponent.visibility - 1);
|
|
}
|
|
return layer;
|
|
}
|
|
if (node.parent) {
|
|
layer = getCanvasCameraLayer(node.parent);
|
|
}
|
|
return layer;
|
|
} |