import { Constructor, director, error, find, instantiate, Node, Prefab, resources, Scene } from "cc"; import { UIBase, UIType } from "../Game/GameFrameWork/UIBase"; class UIManager { static instance: UIManager = null; private _uis: Map = new Map(); private _uiNodes: Map = new Map(); private _prefabs: Map = new Map(); //获取UI getUI(name: string | Constructor): T { if (typeof (name) === "string") { return this._uis.get(name); } //遍历所有的value组成的数组 for (const ui of Array.from(this._uis.values())) { if (ui instanceof name) { return ui; } } return null; } //打开页面 全屏 弹窗 挂件 async openUI(preName: string, type: UIType = UIType.PAGE) { let ui = this._uis.get(preName); if (ui) { //把ui显示出来 ui.show(); return; } //是否在节点容器当中 let node = this._uiNodes.get(preName); if (node) { node.active = true; return; } //node 不存在的情况下 加载出来 //先判断一下预制体是否下载过 let prefab = this._prefabs.get(preName); if (!prefab) { prefab = await this._loadUI("UI/" + preName); this._prefabs.set(preName, prefab) } //查找ui根节点 node = instantiate(prefab); let root = find("Canvas/UIRoot"); if (!root) { //如果场景当中没有 就加载预制体 创建一个 const rootPre: Prefab = await this._loadUI("UI/UIRoot") root = instantiate(rootPre); root.parent = find("Canvas"); } node.parent = root.children[type]; //处理逻辑 ui = node.getComponent(UIBase); if (ui) { //对ui进行多态处理 ui.init(); ui.UIName = preName; this._uis.set(preName, ui); return; } this._uiNodes.set(preName, node); // resources.load("UI/" + preName, Prefab, (err: Error, asset: Prefab)=>{ // const node = instantiate(asset); // node.parent = find("Canvas/UIRoot").children[type]; // //处理逻辑 // const ui = node.getComponent(UIBase); // //对UI进行多态处理 // }) } async openScene(sceneName: string, uiName?: string) { await this._loadScene(sceneName); uiName && this.openUI(uiName); } private _loadScene(sceneName: string) { return new Promise((resolve, reject) => { director.loadScene(sceneName, (err: Error, scene: Scene) => { if (err) { error("加载" + sceneName + "场景错误!"); reject(err); } else { resolve(scene); } }) }) } //加载UI预制体 private _loadUI(path: string): Promise { return new Promise((resvole, reject) => { resources.load(path, Prefab, (err: Error, asset: Prefab) => { if (err) { reject(err); } else { resvole(asset); } }) }) } //关闭UI closeUI(uibase: string | UIBase, clear: boolean = true) { // let ui: UIBase; // if(typeof(uibase) === "string"){ // ui = this._uis.get(uibase); // if(ui){ // ui.hide(clear); // clear && this._uis.delete(uibase); // } // return; // } // uibase.hide(clear); // clear && this._uis.delete(uibase.UIName); // return; let uiName: string; let ui: UIBase | null; let node: Node | null; if (typeof uibase === "string") { uiName = uibase; ui = this._uis.get(uiName); node = this._uiNodes.get(uiName); } else { ui = uibase; uiName = ui.UIName; node = this._uiNodes.get(uiName); } if (ui) { ui.hide(clear); if (clear) { this._uis.delete(uiName); if (ui.node) { ui.node.destroy(); this._uiNodes.delete(uiName); } } } else if (node) { node.active = false; if (clear) { node.destroy(); this._uiNodes.delete(uiName); } } } //UI之间的消息互通 sendMsg(msg: string, ui: string | UIBase, ...args) { let m: UIBase; if (typeof (ui) === "string") { m = this.getUI(ui); } else { m = ui; } //判断如果找到的UI模块是个空 什么也不做 if (!m) { return; } //m 是个对象 找m中有没有 名字叫做msg的函数 //对象都是键值对 访问键对应的值 const func = m[msg]; if (func && typeof (func) === "function") { func.apply(m, [...args]); return; } } } export const UIMgr: UIManager = UIManager.instance = new UIManager();