using System; using System.Collections.Generic; using Cysharp.Threading.Tasks; using TEngine; using UnityEngine; using UnityEngine.UI; using Object = UnityEngine.Object; namespace GameLogic { public abstract class UIWindow : UIBase { #region Propreties private System.Action _prepareCallback; private bool _isCreate = false; private GameObject _panel; private Canvas _canvas; public Canvas Canvas => _canvas; private Canvas[] _childCanvas; private GraphicRaycaster _raycaster; public GraphicRaycaster GraphicRaycaster => _raycaster; private GraphicRaycaster[] _childRaycaster; public override UIType Type => UIType.Window; /// /// 窗口位置组件。 /// public override Transform transform => _panel.transform; /// /// 窗口矩阵位置组件。 /// public override RectTransform rectTransform => _panel.transform as RectTransform; /// /// 窗口的实例资源对象。 /// public override GameObject gameObject => _panel; /// /// 窗口名称。 /// public string WindowName { private set; get; } /// /// 窗口层级。 /// public int WindowLayer { private set; get; } /// /// 资源定位地址。 /// public string AssetName { private set; get; } /// /// 是否为全屏窗口。 /// public virtual bool FullScreen { private set; get; } = false; /// /// 是内部资源无需AB加载。 /// public bool FromResources { private set; get; } /// /// 隐藏窗口关闭时间。 /// public int HideTimeToClose { get; set; } public int HideTimerId { get; set; } /// /// 窗口深度值。 /// 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; } } // 虚函数 if (_isCreate) { OnSortDepth(value); } } } } /// /// 窗口可见性。 /// public bool Visible { get { if (_canvas != null) { return _canvas.gameObject.layer == UIModule.WINDOW_SHOW_LAYER; } else { return false; } } set { if (_canvas != null) { int setLayer = value ? UIModule.WINDOW_SHOW_LAYER : UIModule.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; // 虚函数 if (_isCreate) { OnSetVisible(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; } } } } /// /// 是否加载完毕。 /// internal bool IsLoadDone = false; /// /// UI是否销毁。 /// internal bool IsDestroyed = false; /// /// UI是否隐藏标志位。 /// public bool IsHide { internal set; get; } = false; #endregion public void Init(string name, int layer, bool fullScreen, string assetName, bool fromResources, int hideTimeToClose) { WindowName = name; WindowLayer = layer; FullScreen = fullScreen; AssetName = assetName; FromResources = fromResources; HideTimeToClose = hideTimeToClose; } internal void TryInvoke(System.Action prepareCallback, System.Object[] userDatas) { CancelHideToCloseTimer(); base._userDatas = userDatas; if (IsPrepare) { prepareCallback?.Invoke(this); } else { _prepareCallback = prepareCallback; } } internal async UniTaskVoid InternalLoad(string location, Action prepareCallback, bool isAsync, System.Object[] userDatas) { _prepareCallback = prepareCallback; this._userDatas = userDatas; if (!FromResources) { if (isAsync) { var uiInstance = await UIModule.Resource.LoadGameObjectAsync(location, parent: UIModule.UIRoot); Handle_Completed(uiInstance); } else { var uiInstance = UIModule.Resource.LoadGameObject(location, parent: UIModule.UIRoot); Handle_Completed(uiInstance); } } else { GameObject panel = Object.Instantiate(Resources.Load(location), UIModule.UIRoot); Handle_Completed(panel); } } internal void InternalCreate() { if (_isCreate == false) { _isCreate = true; ScriptGenerator(); BindMemberProperty(); RegisterEvent(); OnCreate(); } } internal void InternalRefresh() { OnRefresh(); } internal bool InternalUpdate() { if (!IsPrepare || !Visible) { return false; } List listNextUpdateChild = null; if (ListChild != null && ListChild.Count > 0) { listNextUpdateChild = _listUpdateChild; var updateListValid = _updateListValid; List listChild = null; if (!updateListValid) { if (listNextUpdateChild == null) { listNextUpdateChild = new List(); _listUpdateChild = listNextUpdateChild; } else { listNextUpdateChild.Clear(); } listChild = ListChild; } else { listChild = listNextUpdateChild; } for (int i = 0; i < listChild.Count; i++) { var uiWidget = listChild[i]; if (uiWidget == null) { continue; } var needValid = uiWidget.InternalUpdate(); if (!updateListValid && needValid) { listNextUpdateChild.Add(uiWidget); } } if (!updateListValid) { _updateListValid = true; } } bool needUpdate = false; if (listNextUpdateChild == null || listNextUpdateChild.Count <= 0) { _hasOverrideUpdate = true; OnUpdate(); needUpdate = _hasOverrideUpdate; } else { OnUpdate(); needUpdate = true; } return needUpdate; } internal void InternalDestroy(bool isShutDown = false) { _isCreate = false; RemoveAllUIEvent(); for (int i = 0; i < ListChild.Count; i++) { var uiChild = ListChild[i]; uiChild.CallDestroy(); uiChild.OnDestroyWidget(); } // 注销回调函数 _prepareCallback = null; OnDestroy(); // 销毁面板对象 if (_panel != null) { Object.Destroy(_panel); _panel = null; } IsDestroyed = true; if (!isShutDown) { CancelHideToCloseTimer(); } } /// /// 处理资源加载完成回调。 /// /// 面板资源实例。 private void Handle_Completed(GameObject panel) { if (panel == null) { return; } IsLoadDone = true; if (IsDestroyed) { Object.Destroy(panel); return; } panel.name = GetType().Name; _panel = panel; _panel.transform.localPosition = Vector3.zero; // 获取组件 _canvas = _panel.GetComponent(); if (_canvas == null) { throw new Exception($"Not found {nameof(Canvas)} in panel {WindowName}"); } _canvas.overrideSorting = true; _canvas.sortingOrder = 0; _canvas.sortingLayerName = "Default"; // 获取组件 _raycaster = _panel.GetComponent(); _childCanvas = _panel.GetComponentsInChildren(true); _childRaycaster = _panel.GetComponentsInChildren(true); // 通知UI管理器 IsPrepare = true; _prepareCallback?.Invoke(this); } protected virtual void Hide() { UIModule.Instance.HideUI(this.GetType()); } protected virtual void Close() { UIModule.Instance.CloseUI(this.GetType()); } internal void CancelHideToCloseTimer() { IsHide = false; if (HideTimerId > 0) { ModuleSystem.GetModule().RemoveTimer(HideTimerId); HideTimerId = 0; } } } }