Files
cocos-creator-multiplayer/examples/cocos-creator-multiplayer/frontend/assets/migrate-canvas.ts
T
2021-12-02 00:38:28 +08:00

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