diff --git a/assets/core/gui/layer/Defines.ts b/assets/core/gui/layer/Defines.ts index 29272db..b1a5f4f 100644 --- a/assets/core/gui/layer/Defines.ts +++ b/assets/core/gui/layer/Defines.ts @@ -5,6 +5,7 @@ * @LastEditTime: 2023-01-09 11:52:38 */ import { Node } from "cc"; +import { UIConfig } from "./LayerManager"; /*** 界面回调参数对象定义 */ export interface UICallbacks { @@ -23,8 +24,6 @@ export interface UICallbacks { onRemoved?: (node: Node | null, params: any) => void, /** - * 注意:调用`delete`或`$delete`才会触发此回调,如果`this.node.destroy()`,该回调将直接忽略。 - * * 如果指定onBeforeRemoved,则next必须调用,否则节点不会被正常删除。 * * 比如希望节点做一个FadeOut然后删除,则可以在`onBeforeRemoved`当中播放action动画,动画结束后调用next @@ -34,21 +33,10 @@ export interface UICallbacks { onBeforeRemove?: (node: Node, next: Function) => void } -/** 弹框层回调对象定义 */ -export interface PopViewParams extends UICallbacks { - /** 是否触摸背景关闭弹窗 */ - touchClose?: boolean, - - /** 控制暗色背景的透明度 默认为190*/ - opacity?: number; -} - /** 本类型仅供gui模块内部使用,请勿在功能逻辑中使用 */ export class ViewParams { - /** 界面唯一标识 */ - uuid: string = null!; - /** 预制路径 */ - prefabPath: string = null!; + /** 界面配置 */ + config: UIConfig = null!; /** 传递给打开界面的参数 */ params: any = null!; /** 窗口事件 */ @@ -57,4 +45,13 @@ export class ViewParams { valid: boolean = true; /** 界面根节点 */ node: Node = null!; +} + +/** 弹框层回调对象定义(废弃) */ +export interface PopViewParams extends UICallbacks { + /** 是否触摸背景关闭弹窗 */ + touchClose?: boolean, + + /** 控制暗色背景的透明度 默认为190*/ + opacity?: number; } \ No newline at end of file diff --git a/assets/core/gui/layer/DelegateComponent.ts b/assets/core/gui/layer/DelegateComponent.ts index 963dbc1..cdb2d3a 100644 --- a/assets/core/gui/layer/DelegateComponent.ts +++ b/assets/core/gui/layer/DelegateComponent.ts @@ -14,50 +14,58 @@ const { ccclass } = _decorator; @ccclass('DelegateComponent') export class DelegateComponent extends Component { /** 视图参数 */ - viewParams: ViewParams = null!; + vp: ViewParams = null!; + /** 界面关闭回调 - 包括关闭动画播放完 */ + onHide: Function = null!; /** 窗口添加 */ add() { // 触发窗口组件上添加到父节点后的事件 - this.applyComponentsFunction(this.node, "onAdded", this.viewParams.params); - if (typeof this.viewParams.callbacks.onAdded === "function") { - this.viewParams.callbacks.onAdded(this.node, this.viewParams.params); + this.applyComponentsFunction(this.node, "onAdded", this.vp.params); + if (typeof this.vp.callbacks.onAdded === "function") { + this.vp.callbacks.onAdded(this.node, this.vp.params); } } /** 删除节点,该方法只能调用一次,将会触发onBeforeRemoved回调 */ - remove(isDestroy: boolean) { - if (this.viewParams.valid) { - // 触发窗口组件上移除之前的事件 - this.applyComponentsFunction(this.node, "onBeforeRemove", this.viewParams.params); + remove(isDestroy?: boolean) { + if (this.vp.valid) { + // 触发窗口移除舞台之前事件 + this.applyComponentsFunction(this.node, "onBeforeRemove", this.vp.params); // 通知外部对象窗口组件上移除之前的事件(关闭窗口前的关闭动画处理) - if (typeof this.viewParams.callbacks.onBeforeRemove === "function") { - this.viewParams.callbacks.onBeforeRemove( + if (typeof this.vp.callbacks.onBeforeRemove === "function") { + this.vp.callbacks.onBeforeRemove( this.node, () => { - this.removed(this.viewParams, isDestroy); + this.removed(this.vp, isDestroy); }); } else { - this.removed(this.viewParams, isDestroy); + this.removed(this.vp, isDestroy); } } } /** 窗口组件中触发移除事件与释放窗口对象 */ - private removed(viewParams: ViewParams, isDestroy: boolean) { - viewParams.valid = false; + private removed(vp: ViewParams, isDestroy?: boolean) { + vp.valid = false; - if (typeof viewParams.callbacks.onRemoved === "function") { - viewParams.callbacks!.onRemoved(this.node, viewParams.params); + if (typeof vp.callbacks.onRemoved === "function") { + vp.callbacks!.onRemoved(this.node, vp.params); } + // 界面移除舞台事件 + this.onHide && this.onHide(vp); + if (isDestroy) { + // 释放界面显示对象 this.node.destroy(); // 释放界面相关资源 - oops.res.release(viewParams.prefabPath); + oops.res.release(vp.config.prefab); + + // oops.log.logView(`【界面管理】释放【${vp.config.prefab}】界面资源`); } else { this.node.removeFromParent(); @@ -66,14 +74,8 @@ export class DelegateComponent extends Component { onDestroy() { // 触发窗口组件上窗口移除之后的事件 - this.applyComponentsFunction(this.node, "onRemoved", this.viewParams.params); - - // 通知外部对象窗口移除之后的事件 - // if (typeof this.viewParams.callbacks!.onRemoved === "function") { - // this.viewParams.callbacks!.onRemoved(this.node, this.viewParams.params); - // } - - this.viewParams = null!; + this.applyComponentsFunction(this.node, "onRemoved", this.vp.params); + this.vp = null!; } protected applyComponentsFunction(node: Node, funName: string, params: any) { diff --git a/assets/core/gui/layer/LayerDialog.ts b/assets/core/gui/layer/LayerDialog.ts index 4542c7e..f4a7ec6 100644 --- a/assets/core/gui/layer/LayerDialog.ts +++ b/assets/core/gui/layer/LayerDialog.ts @@ -23,54 +23,53 @@ type DialogParam = { export class LayerDialog extends LayerPopUp { /** 窗口调用参数队列 */ private params: Array = []; - /** 当前窗口数据 */ - private current!: ViewParams; - add(config: UIConfig, params?: any, callbacks?: UICallbacks): string { - this.black.enabled = true; - - if (this.current && this.current.valid) { - let uuid = this.getUuid(config.prefab); + add(config: UIConfig, params?: any, callbacks?: UICallbacks) { + // 控制同一时间只能显示一个模式窗口 + if (this.ui_nodes.size > 0) { this.params.push({ config: config, params: params, callbacks: callbacks, }); - return uuid; + return; } - return this.show(config, params, callbacks); + + this.black.enabled = true; + this.show(config, params, callbacks); } + /** 显示模式弹窗 */ private show(config: UIConfig, params?: any, callbacks?: UICallbacks): string { - let prefabPath = config.prefab - var uuid = this.getUuid(prefabPath); - var viewParams = this.ui_nodes.get(uuid); - if (viewParams == null) { - viewParams = new ViewParams(); - viewParams.uuid = this.getUuid(prefabPath); - viewParams.prefabPath = prefabPath; - viewParams.valid = true; - this.ui_nodes.set(viewParams.uuid, viewParams); + var vp = this.ui_cache.get(config.prefab); + if (vp == null) { + vp = new ViewParams(); + vp.config = config + vp.valid = true; } + this.ui_nodes.set(vp.config.prefab, vp); - viewParams.callbacks = callbacks ?? {}; - var onRemove_Source = viewParams.callbacks.onRemoved; - viewParams.callbacks.onRemoved = (node: Node | null, params: any) => { + vp.callbacks = callbacks ?? {}; + var onRemove_Source = vp.callbacks.onRemoved; + vp.callbacks.onRemoved = (node: Node | null, params: any) => { if (onRemove_Source) { onRemove_Source(node, params); } setTimeout(this.next.bind(this), 0); }; - viewParams.params = params || {}; - this.current = viewParams; - this.load(viewParams, config.bundle); + vp.params = params || {}; + this.load(vp, config.bundle); - return uuid; + return config.prefab; } protected setBlackDisable() { - if (this.params.length == 0) this.black.enabled = false; + if (this.params.length == 0) { + this.black.enabled = false; + this.closeVacancyRemove(); + this.closeMask() + } } private next() { diff --git a/assets/core/gui/layer/LayerManager.ts b/assets/core/gui/layer/LayerManager.ts index c5a4034..1238515 100644 --- a/assets/core/gui/layer/LayerManager.ts +++ b/assets/core/gui/layer/LayerManager.ts @@ -50,8 +50,15 @@ export interface UIConfig { layer: LayerType; /** 预制资源相对路径 */ prefab: string; + /** 是否触摸非窗口区域关闭 */ + vacancy?: boolean, + /** 是否打开窗口后显示背景遮罩 */ + mask?: boolean; + /** 是否自动施放 */ + destroy?: boolean; } +/** 界面层级管理器 */ export class LayerManager { /** 界面根节点 */ root!: Node; @@ -260,16 +267,16 @@ export class LayerManager { var result: Node = null!; switch (config.layer) { case LayerType.UI: - result = this.ui.getByPrefabPath(config.prefab); + result = this.ui.get(config.prefab); break; case LayerType.PopUp: - result = this.popup.getByPrefabPath(config.prefab); + result = this.popup.get(config.prefab); break; case LayerType.Dialog: - result = this.dialog.getByPrefabPath(config.prefab); + result = this.dialog.get(config.prefab); break; case LayerType.System: - result = this.system.getByPrefabPath(config.prefab); + result = this.system.get(config.prefab); break; } return result; @@ -282,7 +289,7 @@ export class LayerManager { * @example * oops.gui.remove(UIID.Loading); */ - remove(uiId: number, isDestroy: boolean = true) { + remove(uiId: number, isDestroy?: boolean) { var config = this.configs[uiId]; if (config == null) { warn(`删除编号为【${uiId}】的界面失败,配置信息不存在`); @@ -308,16 +315,39 @@ export class LayerManager { /** * 删除一个通过this框架添加进来的节点 * @param node 窗口节点 - * @param isDestroy 移除后是否释放 + * @param isDestroy 移除后是否释放资源 * @example * oops.gui.removeByNode(cc.Node); */ - removeByNode(node: Node, isDestroy: boolean = false) { + removeByNode(node: Node, isDestroy?: boolean) { if (node instanceof Node) { let comp = node.getComponent(DelegateComponent); - if (comp && comp.viewParams) { - // @ts-ignore 注:不对外使用 - (node.parent as LayerUI).removeByUuid(comp.viewParams.uuid, isDestroy); + if (comp && comp.vp) { + // 释放显示的界面 + if (node.parent) { + (node.parent as LayerUI).remove(comp.vp.config.prefab, isDestroy); + } + // 释放缓存中的界面 + else if (isDestroy) { + switch (comp.vp.config.layer) { + case LayerType.UI: + // @ts-ignore 注:不对外使用 + this.ui.removeCache(comp.vp.config.prefab); + break; + case LayerType.PopUp: + // @ts-ignore 注:不对外使用 + this.popup.removeCache(comp.vp.config.prefab); + break; + case LayerType.Dialog: + // @ts-ignore 注:不对外使用 + this.dialog.removeCache(comp.vp.config.prefab); + break; + case LayerType.System: + // @ts-ignore 注:不对外使用 + this.system.removeCache(comp.vp.config.prefab); + break; + } + } } else { warn(`当前删除的node不是通过界面管理器添加到舞台上`); diff --git a/assets/core/gui/layer/LayerPopup.ts b/assets/core/gui/layer/LayerPopup.ts index f89e29d..9a05a40 100644 --- a/assets/core/gui/layer/LayerPopup.ts +++ b/assets/core/gui/layer/LayerPopup.ts @@ -4,16 +4,20 @@ * @LastEditTime: 2022-09-02 13:44:28 */ -import { BlockInputEvents, Layers } from "cc"; -import { PopViewParams } from "./Defines"; +import { BlockInputEvents, EventTouch, Layers, Node } from "cc"; +import { ViewUtil } from "../../utils/ViewUtil"; +import { ViewParams } from "./Defines"; import { UIConfig } from "./LayerManager"; import { LayerUI } from "./LayerUI"; -/* - * 弹窗层,允许同时弹出多个窗口,弹框参数可以查看 PopViewParams - */ +const Mask: string = 'common/prefab/mask'; + +/* 弹窗层,允许同时弹出多个窗口 */ export class LayerPopUp extends LayerUI { + /** 触摸事件阻挡 */ protected black!: BlockInputEvents; + /** 半透明遮罩资源 */ + protected mask!: Node; constructor(name: string) { super(name); @@ -26,34 +30,95 @@ export class LayerPopUp extends LayerUI { this.black.enabled = false; } - /** - * 添加一个预制件节点到PopUp层容器中,该方法将返回一个唯一uuid来标识该操作节点 - * @param prefabPath 预制件路径 - * @param params 传给组件onAdded、onRemoved方法的参数。 - * @param popParams 弹出界面的设置定义,详情见PopViewParams - */ - add(config: UIConfig, params: any, popParams?: PopViewParams): string { + protected showUi(vp: ViewParams) { + super.showUi(vp); + + // 界面加载完成显示时,启动触摸非窗口区域关闭 + this.openVacancyRemove(vp.config); + + // 界面加载完成显示时,层级事件阻挡 this.black.enabled = true; - return super.add(config, params, popParams); } - remove(prefabPath: string, isDestroy: boolean): void { - super.remove(prefabPath, isDestroy); - this.setBlackDisable(); - } - - protected removeByUuid(prefabPath: string, isDestroy: boolean): void { - super.removeByUuid(prefabPath, isDestroy); + protected onHide(vp: ViewParams) { + super.onHide(vp); + + // 界面关闭后,关闭触摸事件阻挡、关闭触摸非窗口区域关闭、关闭遮罩 this.setBlackDisable(); } + /** 设置触摸事件阻挡 */ protected setBlackDisable() { - this.black.enabled = false; + // 所有弹窗关闭后,关闭事件阻挡功能 + if (this.ui_nodes.size == 0) { + this.black.enabled = false; + } + this.closeVacancyRemove(); + this.closeMask(); + } + + /** 关闭遮罩 */ + protected closeMask() { + var flag = true; + for (var value of this.ui_nodes.values()) { + if (value.config.mask) { + flag = false; + break; + } + } + + if (flag) { + this.mask.parent = null; + } + } + + /** 启动触摸非窗口区域关闭 */ + protected openVacancyRemove(config: UIConfig) { + if (!this.hasEventListener(Node.EventType.TOUCH_END, this.onTouchEnd, this)) { + this.on(Node.EventType.TOUCH_END, this.onTouchEnd, this); + } + + // 背景半透明遮罩 + if (this.mask == null) { + this.mask = ViewUtil.createPrefabNode(Mask); + } + if (config.mask) { + this.mask.parent = this; + this.mask.setSiblingIndex(0); + } + } + + /** 关闭触摸非窗口区域关闭 */ + protected closeVacancyRemove() { + var flag = true; + for (var value of this.ui_nodes.values()) { + if (value.config.vacancy) { + flag = false; + break; + } + } + + if (flag && this.hasEventListener(Node.EventType.TOUCH_END, this.onTouchEnd, this)) { + this.off(Node.EventType.TOUCH_END, this.onTouchEnd, this); + } + } + + private onTouchEnd(event: EventTouch) { + if (event.target === this) { + this.ui_nodes.forEach(vp => { + // 关闭已显示的界面 + if (vp.valid && vp.config.vacancy) { + this.remove(vp.config.prefab, true); + } + }); + } } clear(isDestroy: boolean) { super.clear(isDestroy) this.black.enabled = false; this.active = false; + this.closeVacancyRemove(); + this.closeMask(); } } \ No newline at end of file diff --git a/assets/core/gui/layer/LayerUI.ts b/assets/core/gui/layer/LayerUI.ts index e20b4a1..9074ccb 100644 --- a/assets/core/gui/layer/LayerUI.ts +++ b/assets/core/gui/layer/LayerUI.ts @@ -2,14 +2,11 @@ * UI基础层,允许添加多个预制件节点 * add : 添加一个预制件节点到层容器中,该方法将返回一个唯一uuid来标识该操作Node节点。 * delete : 根据uuid删除Node节点,如果节点还在队列中也会被删除, 删除节点可以用gui.delete(node)或this.node.destroy() - * deleteByUuid : 根据预制件路径删除,预制件如在队列中也会被删除,如果该预制件存在多个也会一起删除。 - * get : 根据uuid获取Node节点,如果节点不存在或者预制件还在队列中,则返回null 。 - * getByUuid : 根据预制件路径获取当前显示的该预制件的所有Node节点数组。 + * get : 根据预制路径获取已打开界面的节点对象,如果节点不存在或者预制件还在队列中,则返回null 。 * has : 判断当前层是否包含 uuid或预制件路径对应的Node节点。 - * find : 判断当前层是否包含 uuid或预制件路径对应的Node节点。 * clear : 清除所有Node节点,队列当中未创建的任务也会被清除。 */ -import { error, instantiate, isValid, Node, Prefab, warn, Widget } from "cc"; +import { error, instantiate, Node, Prefab, warn, Widget } from "cc"; import { oops } from "../../Oops"; import { UICallbacks, ViewParams } from "./Defines"; import { DelegateComponent } from "./DelegateComponent"; @@ -17,7 +14,7 @@ import { UIConfig } from "./LayerManager"; /** 界面层对象 */ export class LayerUI extends Node { - /** 界面节点集合 */ + /** 显示界面节点集合 */ protected ui_nodes = new Map(); /** 被移除的界面缓存数据 */ protected ui_cache = new Map(); @@ -37,85 +34,81 @@ export class LayerUI extends Node { widget.enabled = true; } - /** 构造一个唯一标识UUID */ - protected getUuid(prefabPath: string): string { - var uuid = `${this.name}_${prefabPath}`; - return uuid.replace(/\//g, "_"); - } - /** * 添加一个预制件节点到层容器中,该方法将返回一个唯一`uuid`来标识该操作节点 * @param prefabPath 预制件路径 * @param params 自定义参数 * @param callbacks 回调函数对象,可选 + * @returns ture为成功,false为失败 */ - add(config: UIConfig, params?: any, callbacks?: UICallbacks): string { - let prefabPath = config.prefab; - var uuid = this.getUuid(prefabPath); - var viewParams = this.ui_nodes.get(uuid); - - if (viewParams && viewParams.valid) { - warn(`路径为【${prefabPath}】的预制重复加载`); - return ""; + add(config: UIConfig, params?: any, callbacks?: UICallbacks) { + if (this.ui_nodes.has(config.prefab)) { + warn(`路径为【${config.prefab}】的预制重复加载`); + return; } - if (viewParams == null) { - viewParams = new ViewParams(); - viewParams.uuid = uuid; - viewParams.prefabPath = prefabPath; - this.ui_nodes.set(viewParams.uuid, viewParams); + // 检查缓存中是否存界面 + var vp = this.ui_cache.get(config.prefab); + if (vp == null) { + vp = new ViewParams(); + vp.config = config; } + this.ui_nodes.set(config.prefab, vp); - viewParams.params = params ?? {}; - viewParams.callbacks = callbacks ?? {}; - viewParams.valid = true; + vp.params = params ?? {}; + vp.callbacks = callbacks ?? {}; + vp.valid = true; - this.load(viewParams, config.bundle) - - return uuid; + this.load(vp, config.bundle) } /** * 加载界面资源 - * @param viewParams 显示参数 + * @param vp 显示参数 * @param bundle 远程资源包名,如果为空就是默认本地资源包 */ - protected load(viewParams: ViewParams, bundle?: string) { - var vp: ViewParams = this.ui_nodes.get(viewParams.uuid)!; + protected load(vp: ViewParams, bundle?: string) { if (vp && vp.node) { - this.createNode(vp); + this.showUi(vp); } else { // 优先加载配置的指定资源包中资源,如果没配置则加载默认资源包资源 bundle = bundle || oops.res.defaultBundleName; - oops.res.load(bundle, viewParams.prefabPath, (err: Error | null, res: Prefab) => { + oops.res.load(bundle, vp.config.prefab, (err: Error | null, res: Prefab) => { if (err) { - this.ui_nodes.delete(viewParams.uuid); - error(`路径为【${viewParams.prefabPath}】的预制加载失败`); + this.ui_nodes.delete(vp.config.prefab); + error(`路径为【${vp.config.prefab}】的预制加载失败`); return; } let childNode: Node = instantiate(res); - viewParams.node = childNode; + vp.node = childNode; let comp = childNode.addComponent(DelegateComponent); - comp.viewParams = viewParams; + comp.vp = vp; + comp.onHide = this.onHide.bind(this); - this.createNode(viewParams); + this.showUi(vp); }); } } + protected onHide(vp: ViewParams) { + this.ui_nodes.delete(vp.config.prefab); + } + /** * 创建界面节点 - * @param viewParams 视图参数 + * @param vp 视图参数 */ - protected createNode(viewParams: ViewParams) { - viewParams.valid = true; - - let comp = viewParams.node.getComponent(DelegateComponent)!; + protected showUi(vp: ViewParams) { + // 触发窗口添加事件 + let comp = vp.node.getComponent(DelegateComponent)!; comp.add(); - viewParams.node.parent = this; + vp.node.parent = this; + + // 标记界面为使用状态 + vp.valid = true; } /** @@ -123,55 +116,40 @@ export class LayerUI extends Node { * @param prefabPath 预制路径 * @param isDestroy 移除后是否释放 */ - remove(prefabPath: string, isDestroy: boolean): void { - // 验证是否删除后台缓存界面 - if (isDestroy) this.removeCache(prefabPath); + remove(prefabPath: string, isDestroy?: boolean): void { + var release = true; + // 默认不配置为关闭界面释放资源 + if (isDestroy == undefined) release = true; // 界面移出舞台 - let children = this.__nodes(); - for (let i = 0; i < children.length; i++) { - let viewParams = children[i].viewParams; - if (viewParams.prefabPath === prefabPath) { - if (isDestroy) { - // 直接释放界面 - this.ui_nodes.delete(viewParams.uuid); - } - else { - // 不释放界面,缓存起来待下次使用 - this.ui_cache.set(viewParams.prefabPath, viewParams); - } - - children[i].remove(isDestroy); - viewParams.valid = false; + var vp = this.ui_nodes.get(prefabPath); + if (vp) { + // 优先使用参数中控制的释放条件,如果未传递参数则用配置中的释放条件 + if (isDestroy == undefined && vp.config.destroy != undefined) { + release = vp.config.destroy; } - } - } - /** - * 根据唯一标识删除节点,如果节点还在队列中也会被删除 - * @param uuid 唯一标识 - */ - protected removeByUuid(uuid: string, isDestroy: boolean): void { - var viewParams = this.ui_nodes.get(uuid); - if (viewParams) { - if (isDestroy) - this.ui_nodes.delete(viewParams.uuid); + // 不释放界面,缓存起来待下次使用 + if (!release) { + this.ui_cache.set(vp.config.prefab, vp); + } - var childNode = viewParams.node; + var childNode = vp.node; var comp = childNode.getComponent(DelegateComponent)!; - comp.remove(isDestroy); + comp.remove(release); } + + // 验证是否删除后台缓存界面 + if (release) this.removeCache(prefabPath); } - /** - * 删除缓存的界面,当缓存界面被移除舞台时,可通过此方法删除缓存界面 - */ + /** 删除缓存的界面,当缓存界面被移除舞台时,可通过此方法删除缓存界面 */ private removeCache(prefabPath: string) { - let viewParams = this.ui_cache.get(prefabPath); - if (viewParams) { - this.ui_nodes.delete(viewParams.uuid); + let vp = this.ui_cache.get(prefabPath); + if (vp) { + this.ui_nodes.delete(vp.config.prefab); this.ui_cache.delete(prefabPath); - var childNode = viewParams.node; + var childNode = vp.node; childNode.destroy(); } } @@ -180,80 +158,19 @@ export class LayerUI extends Node { * 根据预制路径获取已打开界面的节点对象 * @param prefabPath 预制路径 */ - getByPrefabPath(prefabPath: string): Node { - var uuid = this.getUuid(prefabPath); - return this.getByUuid(uuid); - } - - /** - * 根据唯一标识获取节点,如果节点不存在或者还在队列中,则返回null - * @param uuid 唯一标识 - */ - getByUuid(uuid: string): Node { - let children = this.__nodes(); - for (let comp of children) { - if (comp.viewParams && comp.viewParams.uuid === uuid) { - return comp.node; - } - } + get(prefabPath: string): Node { + var vp = this.ui_nodes.get(prefabPath); + if (vp) + return vp.node; return null!; } - /** - * 根据预制件路径获取当前显示的该预制件的所有Node节点数组 - * @param prefabPath - */ - get(prefabPath: string): Array { - let arr: Array = []; - let children = this.__nodes(); - for (let comp of children) { - if (comp.viewParams.prefabPath === prefabPath) { - arr.push(comp.node); - } - } - return arr; - } - /** * 判断当前层是否包含 uuid或预制件路径对应的Node节点 - * @param prefabPathOrUUID 预制件路径或者UUID + * @param prefabPath 预制件路径或者UUID */ - has(prefabPathOrUUID: string): boolean { - let children = this.__nodes(); - for (let comp of children) { - if (comp.viewParams.uuid === prefabPathOrUUID || comp.viewParams.prefabPath === prefabPathOrUUID) { - return true; - } - } - return false; - } - - /** - * 获取当前层包含指定正则匹配的Node节点。 - * @param prefabPathReg 匹配预制件路径的正则表达式对象 - */ - find(prefabPathReg: RegExp): Node[] { - let arr: Node[] = []; - let children = this.__nodes(); - for (let comp of children) { - if (prefabPathReg.test(comp.viewParams.prefabPath)) { - arr.push(comp.node); - } - } - return arr; - } - - /** 获取当前层所有窗口事件触发组件 */ - protected __nodes(): Array { - let result: Array = []; - let children = this.children; - for (let i = 0; i < children.length; i++) { - let comp = children[i].getComponent(DelegateComponent); - if (comp && comp.viewParams && comp.viewParams.valid && isValid(comp)) { - result.push(comp); - } - } - return result; + has(prefabPath: string): boolean { + return this.ui_nodes.has(prefabPath); } /** @@ -263,7 +180,7 @@ export class LayerUI extends Node { clear(isDestroy: boolean): void { // 清除所有显示的界面 this.ui_nodes.forEach((value: ViewParams, key: string) => { - this.removeByUuid(value.uuid, isDestroy); + this.remove(value.config.prefab, isDestroy); value.valid = false; }); this.ui_nodes.clear(); diff --git a/assets/libs/animator-effect/3d/NavLine.ts b/assets/libs/animator-effect/3d/NavLine.ts index 9466335..c39bed8 100644 --- a/assets/libs/animator-effect/3d/NavLine.ts +++ b/assets/libs/animator-effect/3d/NavLine.ts @@ -5,6 +5,7 @@ * @LastEditTime: 2022-03-25 23:43:25 */ +import { Material } from 'cc'; import { Color, Component, macro, MeshRenderer, Node, renderer, v2, Vec2, Vec3, _decorator } from 'cc'; const { ccclass, property } = _decorator; @@ -32,7 +33,7 @@ export class NavLine extends Component { xEuler = true; /* 材质 */ - private mat: renderer.MaterialInstance = null!; + private mat: Material | renderer.MaterialInstance | null = null!; /* 导航线是否启动 */ private inited = false; @@ -56,7 +57,7 @@ export class NavLine extends Component { this.mesh.node.active = true; this.frame = 0; this.inited = true; - this.mat.setProperty("mainColor", this.color); + this.mat?.setProperty("mainColor", this.color); this.start_pos.set(this.player.worldPosition); this.target_pos.set(pos); @@ -76,7 +77,7 @@ export class NavLine extends Component { this.node.setScale(this.node.scale.x, this.node.scale.y, this.distance); this.node.setWorldPosition(this.player.worldPosition); this.tOffset.y = this.distance * this.density; - this.mat.setProperty("tilingOffset", this.tOffset); + this.mat?.setProperty("tilingOffset", this.tOffset); if (this.xEuler) this.rotation(this.start_pos, this.target_pos); } diff --git a/assets/module/common/ModuleUtil.ts b/assets/module/common/ModuleUtil.ts index e1a6c76..eb31024 100644 --- a/assets/module/common/ModuleUtil.ts +++ b/assets/module/common/ModuleUtil.ts @@ -60,7 +60,7 @@ export class ModuleUtil { * @param uiId 界面资源编号 * @param isDestroy 是否释放界面缓存 */ - public static removeView(ent: ecs.Entity, ctor: CompType, uiId: number, isDestroy: boolean = true) { + public static removeView(ent: ecs.Entity, ctor: CompType, uiId: number, isDestroy?: boolean) { ent.remove(ctor); oops.gui.remove(uiId, isDestroy); }