| | |
| | | #endregion
|
| | |
|
| | | #region UI资源管理
|
| | | |
| | | // 加载UI预制体
|
| | | private T LoadUIResource<T>(string uiName) where T : UIBase
|
| | |
|
| | | private UIBase LoadUIResource(string uiName)
|
| | | {
|
| | | // 从资源管理器加载UI预制体
|
| | | GameObject prefab = ResManager.Instance.LoadAsset<GameObject>("UI", uiName);
|
| | |
| | | GameObject uiObject = GameObject.Instantiate(prefab);
|
| | | // 设置对象名称
|
| | | uiObject.name = uiName;
|
| | |
|
| | | // 通过uiName映射Type
|
| | | Type uiType = Type.GetType(uiName);
|
| | | if (uiType == null)
|
| | | {
|
| | | Debug.LogError($"找不到UI类型: {uiName}");
|
| | | return null;
|
| | | }
|
| | |
|
| | | // 获取UI基类组件
|
| | | T uiBase = uiObject.GetComponent<T>();
|
| | | UIBase uiBase = uiObject.GetComponent(uiType) as UIBase;
|
| | |
|
| | | // 检查UI基类组件是否存在
|
| | | if (uiBase == null)
|
| | | {
|
| | | // 记录错误日志
|
| | | Debug.LogError($"UI预制体 {uiName} 没有 UIBase 组件");
|
| | | Debug.LogError($"UI预制体 {uiName} 没有 UIBase 组件或类型不匹配");
|
| | | return null;
|
| | | }
|
| | |
|
| | | // 设置UI名称
|
| | | uiBase.uiName = uiName;
|
| | | // // 设置UI实例ID
|
| | | // uiBase.instanceID = GenerateUIInstanceID(uiName);
|
| | |
|
| | | // 设置父节点为UI根节点
|
| | | Transform parentTrans = GetTransForLayer(uiBase.uiLayer);
|
| | |
|
| | | uiObject.transform.SetParent(parentTrans, false);
|
| | |
|
| | | // Debug.LogError("加载UI资源-SetParent " + uiName + " transName is " + parentTrans.gameObject.name);
|
| | |
|
| | | // 设置排序顺序
|
| | | int baseSortingOrder = GetBaseSortingOrderForLayer(uiBase.uiLayer);
|
| | | uiBase.SetSortingOrder(baseSortingOrder);
|
| | |
|
| | | return uiBase;
|
| | | }
|
| | |
|
| | | // 加载UI预制体
|
| | | private T LoadUIResource<T>(string uiName) where T : UIBase
|
| | | {
|
| | | return LoadUIResource(uiName) as T;
|
| | | }
|
| | |
|
| | | #endregion
|
| | |
| | | #endregion
|
| | |
|
| | | #region UI操作
|
| | | |
| | | /// <summary>
|
| | | /// 打开UI
|
| | | /// </summary>
|
| | | public T OpenWindow<T>(UIBase parentUI = null) where T : UIBase
|
| | |
|
| | |
|
| | |
|
| | | private UIBase GetLastSupportParentChildRelationUI()
|
| | | {
|
| | | // 获取UI类型名称
|
| | | string uiName = typeof(T).Name;
|
| | | |
| | | List<UIBase> tempList = new List<UIBase>();
|
| | |
|
| | | UIBase target = null;
|
| | |
|
| | | while (target == null && uiStack.Count > 0)
|
| | | {
|
| | | UIBase uiBase = uiStack.Pop();
|
| | |
|
| | | if (uiBase != null && uiBase.supportParentChildRelation && !uiBase.isMainUI)
|
| | | {
|
| | | target = uiBase;
|
| | | }
|
| | |
|
| | | tempList.Add(uiBase);
|
| | | }
|
| | |
|
| | | for (int i = tempList.Count - 1; i >= 0; i--)
|
| | | {
|
| | | uiStack.Push(tempList[i]);
|
| | | }
|
| | |
|
| | | return target;
|
| | | }
|
| | |
|
| | | public UIBase OpenWindow(string uiName)
|
| | | {
|
| | | // 优先从closedUIDict中获取
|
| | | UIBase parentUI = null;
|
| | |
|
| | | UIBase returnValue = null;
|
| | |
|
| | | if (closedUIDict.TryGetValue(uiName, out List<UIBase> closedUIList) && closedUIList.Count > 0)
|
| | | {
|
| | | T recycledUI = closedUIList[0] as T;
|
| | | returnValue = closedUIList[0] as UIBase;
|
| | | closedUIList.RemoveAt(0);
|
| | |
|
| | | if (closedUIList.Count == 0)
|
| | | {
|
| | | closedUIDict.Remove(uiName);
|
| | | }
|
| | | |
| | | recycledUI.gameObject.SetActive(true);
|
| | | |
| | | // 自动设置父级UI(如果未指定且支持父子关系)
|
| | | if (parentUI == null && recycledUI.supportParentChildRelation && uiStack.Count > 0)
|
| | | {
|
| | | // 获取栈顶UI
|
| | | UIBase topUI = uiStack.Peek();
|
| | | // 如果栈顶UI也支持父子关系且不是主UI,则将其设为父级
|
| | | if (topUI != null && topUI.supportParentChildRelation && !topUI.isMainUI)
|
| | | {
|
| | | parentUI = topUI;
|
| | | }
|
| | | }
|
| | | |
| | | // 设置父级UI
|
| | | if (parentUI != null && recycledUI.supportParentChildRelation && !parentUI.isMainUI)
|
| | | {
|
| | | // 设置父子关系
|
| | | recycledUI.parentUI = parentUI;
|
| | | if (parentUI.childrenUI == null)
|
| | | {
|
| | | // 初始化父级UI的子UI列表
|
| | | parentUI.childrenUI = new List<UIBase>();
|
| | | }
|
| | | // 添加到父级UI的子UI列表
|
| | | parentUI.childrenUI.Add(recycledUI);
|
| | | }
|
| | | |
| | | // 更新回合数
|
| | | currentRound++;
|
| | | // 设置UI的最后使用回合数
|
| | | recycledUI.lastUsedRound = currentRound;
|
| | | // 更新父级UI的回合数
|
| | | UpdateParentUIRounds(recycledUI);
|
| | | |
| | | // 将UI添加到字典中
|
| | | if (!uiDict.ContainsKey(uiName))
|
| | | {
|
| | | // 如果字典中不存在该类型的UI,创建新列表
|
| | | uiDict[uiName] = new List<UIBase>();
|
| | | }
|
| | | // 添加到UI列表
|
| | | uiDict[uiName].Add(recycledUI);
|
| | | |
| | | // 将UI添加到栈中
|
| | | uiStack.Push(recycledUI);
|
| | | |
| | | // 更新UI排序顺序
|
| | | UpdateUISortingOrder();
|
| | | |
| | | // 打开UI
|
| | | recycledUI.HandleOpen();
|
| | |
|
| | | OnOpenWindow?.Invoke(recycledUI);
|
| | | |
| | | // 检查并关闭长时间未使用的UI
|
| | | CheckAndCloseIdleUI();
|
| | | |
| | | return recycledUI;
|
| | | }
|
| | |
|
| | | // 如果closedUIDict中没有可用的UI实例,则加载新的UI资源
|
| | | // Debug.LogError("打开ui " + uiName);
|
| | |
|
| | | // 加载UI资源
|
| | | T ui = LoadUIResource<T>(uiName);
|
| | | if (ui == null)
|
| | | else
|
| | | {
|
| | | // 记录错误日志
|
| | | Debug.LogError($"打开UI失败: {uiName}");
|
| | | return null;
|
| | | returnValue = LoadUIResource(uiName);
|
| | | if (returnValue == null)
|
| | | {
|
| | | // 记录错误日志
|
| | | Debug.LogError($"打开UI失败: {uiName}");
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
|
| | | // Debug.LogError("加载UI资源 " + uiName);
|
| | | |
| | | returnValue.gameObject.SetActive(true);
|
| | |
|
| | | // 自动设置父级UI(如果未指定且支持父子关系)
|
| | | if (parentUI == null && ui.supportParentChildRelation && uiStack.Count > 0)
|
| | | if (returnValue.supportParentChildRelation && uiStack.Count > 0)
|
| | | {
|
| | | // 获取栈顶UI
|
| | | UIBase topUI = uiStack.Peek();
|
| | | // 如果栈顶UI也支持父子关系且不是主UI,则将其设为父级
|
| | | if (topUI != null && topUI.supportParentChildRelation && !topUI.isMainUI)
|
| | | {
|
| | | parentUI = topUI;
|
| | | }
|
| | | parentUI = GetLastSupportParentChildRelationUI();
|
| | | }
|
| | |
|
| | | // 设置父级UI
|
| | | if (parentUI != null && ui.supportParentChildRelation && !parentUI.isMainUI)
|
| | | if (parentUI != null)
|
| | | {
|
| | | // 设置父子关系
|
| | | ui.parentUI = parentUI;
|
| | | returnValue.parentUI = parentUI;
|
| | | if (parentUI.childrenUI == null)
|
| | | {
|
| | | // 初始化父级UI的子UI列表
|
| | | parentUI.childrenUI = new List<UIBase>();
|
| | | }
|
| | | // 添加到父级UI的子UI列表
|
| | | parentUI.childrenUI.Add(ui);
|
| | | parentUI.childrenUI.Add(returnValue);
|
| | | }
|
| | |
|
| | | // 更新回合数
|
| | | currentRound++;
|
| | | // 设置UI的最后使用回合数
|
| | | ui.lastUsedRound = currentRound;
|
| | | returnValue.lastUsedRound = currentRound;
|
| | | // 更新父级UI的回合数
|
| | | UpdateParentUIRounds(ui);
|
| | | UpdateParentUIRounds(returnValue);
|
| | |
|
| | | // 将UI添加到字典中
|
| | | if (!uiDict.ContainsKey(uiName))
|
| | |
| | | uiDict[uiName] = new List<UIBase>();
|
| | | }
|
| | | // 添加到UI列表
|
| | | uiDict[uiName].Add(ui);
|
| | | uiDict[uiName].Add(returnValue);
|
| | |
|
| | | // 将UI添加到栈中
|
| | | uiStack.Push(ui);
|
| | | uiStack.Push(returnValue);
|
| | |
|
| | | // 更新UI排序顺序
|
| | | UpdateUISortingOrder();
|
| | |
|
| | | // 打开UI
|
| | | ui.HandleOpen();
|
| | | returnValue.HandleOpen();
|
| | |
|
| | | OnOpenWindow?.Invoke(ui);
|
| | | OnOpenWindow?.Invoke(returnValue);
|
| | |
|
| | | // 检查并关闭长时间未使用的UI
|
| | | CheckAndCloseIdleUI();
|
| | |
|
| | | return ui;
|
| | | return returnValue;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 打开UI
|
| | | /// </summary>
|
| | | public T OpenWindow<T>() where T : UIBase
|
| | | {
|
| | | // 获取UI类型名称
|
| | | string uiName = typeof(T).Name;
|
| | | return OpenWindow(uiName) as T;
|
| | | }
|
| | |
|
| | | /// <summary>
|