using System; using System.Collections.Generic; using AlicizaX.Runtime; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.UI; using Object = UnityEngine.Object; namespace AlicizaX.UI.Runtime { public abstract partial class UIWindow : UIBase { internal Canvas _canvas; internal Canvas[] _childCanvas; internal GraphicRaycaster _raycaster; internal GraphicRaycaster[] _childRaycaster; public override string AssetName { get => gameObject.name; } private bool mVisible; public override bool Visible { get { if (_canvas != null) { return _canvas.gameObject.layer == UIComponent.WINDOW_SHOW_LAYER; } else { return false; } } set { if (value == mVisible) { return; } if (value) { OnRegisterEvent(); } else { RemoveAllUIEvent(); } mVisible = value; if (_canvas != null) { int setLayer = value ? UIComponent.WINDOW_SHOW_LAYER : UIComponent.WINDOW_HIDE_LAYER; if (_canvas.gameObject.layer == setLayer) return; _canvas.gameObject.layer = setLayer; for (int i = 0; i < _childCanvas.Length; i++) { _childCanvas[i].gameObject.layer = setLayer; } Interactable = value; } } } private bool Interactable { get { if (_raycaster != null) { return _raycaster.enabled; } else { return false; } } set { if (_raycaster != null) { _raycaster.enabled = value; for (int i = 0; i < _childRaycaster.Length; i++) { _childRaycaster[i].enabled = value; } } } } /// /// 窗口深度值。 /// public int Depth { get { if (_canvas != null) { return _canvas.sortingOrder; } else { return 0; } } set { if (_canvas != null) { if (_canvas.sortingOrder == value) { return; } // 设置父类 _canvas.sortingOrder = value; // 设置子类 int depth = value; for (int i = 0; i < _childCanvas.Length; i++) { var canvas = _childCanvas[i]; if (canvas != _canvas) { depth += 5; //注意递增值 canvas.sortingOrder = depth; } } } } } internal void InternalCreate(GameObject panel) { if (panel == null) { return; } panel.name = GetType().Name; gameObject = panel; panel.transform.localPosition = Vector3.zero; rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; rectTransform.localScale = Vector3.one; // 获取组件 _canvas = panel.GetComponent(); if (_canvas == null) { throw new Exception($"Not found {nameof(Canvas)} in panel {AssetName}"); } _canvas.overrideSorting = true; _canvas.sortingOrder = 0; _canvas.sortingLayerName = "Default"; // 获取组件 _raycaster = panel.GetComponent(); _childCanvas = panel.GetComponentsInChildren(true); _childRaycaster = panel.GetComponentsInChildren(true); IsLoaded = true; } internal void RefreshParams(params System.Object[] userDatas) { this.userDatas = userDatas; } internal void InternalInitlize() { OnBindUIComponents(); OnInitlize(); } internal void InternalOpen() { Visible = true; OnOpen(); WithParentVisible(true, true); } internal bool InternalUpdate() { if (!IsLoaded || !Visible) { return false; } OnUpdate(); return true; } internal void InternalClose() { OnClose(); Visible = false; CollectChildVisible(); WithParentVisible(false, false); } internal void InternalDestroy() { DisposeEvent(); for (int i = 0; i < childWidgets.Count; i++) { var uiChild = childWidgets[i]; uiChild.InternalDestroy(); } childWidgets.Clear(); OnDestroy(); if (gameObject != null) { Object.Destroy(gameObject); gameObject = null; } } protected virtual void OnUpdate() { } /// /// 关闭自己 /// /// 如果有缓存时间 指定该参数可以直接移除 长期缓存的无效 protected void CloseSelf(bool force = false) { GameEntry.GetComponent().CloseUI(this.GetType(), force); } private void CollectChildVisible() { for (int i = 0; i < childWidgets.Count; i++) { var uiChild = childWidgets[i]; if (uiChild.Visible) { withOpenWidget.Add(uiChild); } } } private void WithParentVisible(bool visible, bool clear) { for (int i = 0; i < withOpenWidget.Count; i++) { var uiChild = withOpenWidget[i]; if (visible) { uiChild.InternalRegisterEvent(); } else { uiChild.InternalRemoveAllUIEvent(); } } if (clear) withOpenWidget.Clear(); } } }