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;
|
||
} |