From 7c74e108574002c52dc568c9e7e9b63419ca9f42 Mon Sep 17 00:00:00 2001 From: ALEXTANG <574809918@qq.com> Date: Thu, 17 Aug 2023 10:59:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BE=9B=E5=8D=95=E7=8B=AC=E9=94=80?= =?UTF-8?q?=E6=AF=81UIWidget=E7=9A=84=E6=8E=A5=E5=8F=A3=E3=80=82=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0UIWidget=E5=BC=82=E6=AD=A5=E5=88=9B=E5=BB=BA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 提供单独销毁UIWidget的接口。增加UIWidget异步创建接口。 --- .../Runtime/GameFramework/UI/UIBase.cs | 75 +++++++++++++++--- .../Runtime/GameFramework/UI/UIWidget.cs | 77 ++++++++++++++----- 2 files changed, 122 insertions(+), 30 deletions(-) diff --git a/Assets/TEngine/Runtime/GameFramework/UI/UIBase.cs b/Assets/TEngine/Runtime/GameFramework/UI/UIBase.cs index 606b9549..cbd42650 100644 --- a/Assets/TEngine/Runtime/GameFramework/UI/UIBase.cs +++ b/Assets/TEngine/Runtime/GameFramework/UI/UIBase.cs @@ -42,7 +42,7 @@ namespace TEngine /// UI父节点。 /// public UIBase Parent => parent; - + /// /// 自动逸数据集。 /// @@ -240,8 +240,10 @@ namespace TEngine #endregion #region UIWidget + /// /// 创建UIWidget通过父UI位置节点。 + /// 因为资源示例已经存在父物体所以不需要异步。 /// /// 父UI位置节点。 /// 是否可见。 @@ -255,12 +257,14 @@ namespace TEngine { return CreateWidget(goRootTrans.gameObject, visible); } + return null; } - - + + /// /// 创建UIWidget通过父UI位置节点。 + /// 因为资源示例已经存在父物体所以不需要异步。 /// /// /// 父UI位置节点。 @@ -274,11 +278,13 @@ namespace TEngine { return CreateWidget(goRootTrans.gameObject, visible); } + return null; } /// /// 创建UIWidget通过游戏物体。 + /// 因为资源示例已经存在父物体所以不需要异步。 /// /// 游戏物体。 /// 是否可见。 @@ -291,25 +297,48 @@ namespace TEngine { return widget; } + return null; } /// - /// 创建UIWidget通过资源路径。 + /// 创建UIWidget通过资源定位地址。 /// /// 资源父节点。 - /// 资源路径。 + /// 资源定位地址。 /// 是否可见。 /// UIWidget。 /// UIWidget实例。 - public T CreateWidgetByPath(Transform parentTrans, string assetPath, bool visible = true) where T : UIWidget, new() + public T CreateWidgetByPath(Transform parentTrans, string assetLocation, bool visible = true) where T : UIWidget, new() { if (AssetReference == null) { Log.Fatal($"CreateWidgetByPath Failed => {this}.AssetReference is null"); return null; } - GameObject goInst = AssetReference.LoadAsset(assetPath, parentTrans); + + GameObject goInst = AssetReference.LoadAsset(assetLocation, parentTrans); + return CreateWidget(goInst, visible); + } + + /// + /// 创建UIWidget通过资源定位地址。 + /// + /// 资源父节点。 + /// 资源定位地址。 + /// 是否可见。 + /// UIWidget。 + /// UIWidget实例。 + public async UniTask CreateWidgetByPathAsync(Transform parentTrans, string assetLocation, bool visible = true) where T : UIWidget, new() + { + if (AssetReference == null) + { + Log.Fatal($"CreateWidgetByPath Failed => {this}.AssetReference is null"); + return null; + } + + GameObject goInst = await AssetReference.LoadAssetAsync(assetLocation, gameObject.GetCancellationTokenOnDestroy()); + goInst.transform.SetParent(parentTrans); return CreateWidget(goInst, visible); } @@ -344,6 +373,18 @@ namespace TEngine return CreateWidgetByPath(parentTrans, typeof(T).Name, visible); } + /// + /// 通过UI类型来创建widget。 + /// + /// 资源父节点。 + /// 是否可见。 + /// UIWidget。 + /// UIWidget实例。 + public async UniTask CreateWidgetByTypeAsync(Transform parentTrans, bool visible = true) where T : UIWidget, new() + { + return await CreateWidgetByPathAsync(parentTrans, typeof(T).Name, visible); + } + /// /// 调整图标数量。 /// @@ -354,7 +395,8 @@ namespace TEngine /// 资产副本。 /// 资产地址。 /// 图标类型。 - public void AdjustIconNum(List listIcon, int number, Transform parentTrans, GameObject prefab = null, string assetPath = "") where T : UIWidget, new() + public void AdjustIconNum(List listIcon, int number, Transform parentTrans, GameObject prefab = null, string assetPath = "") + where T : UIWidget, new() { if (listIcon == null) { @@ -475,14 +517,17 @@ namespace TEngine icon.OnDestroy(); icon.OnDestroyWidget(); ListChild.Remove(icon); - UnityEngine.Object.Destroy(icon.gameObject); + if (icon.gameObject != null) + { + UnityEngine.Object.Destroy(icon.gameObject); + } } } #endregion #region AssetRefrence Methods - + /// /// 引用资源数据到资源组内。 /// @@ -496,6 +541,7 @@ namespace TEngine Log.Fatal($"Reference Failed => {this}.AssetReference is null"); return false; } + return AssetReference.Reference(handle, assetTag); } @@ -513,6 +559,7 @@ namespace TEngine Log.Fatal($"Reference Failed => {this}.AssetReference is null"); return false; } + return AssetReference.Reference(address, handle, assetTag); } @@ -528,6 +575,7 @@ namespace TEngine Log.Fatal($"Release Failed => {this}.AssetReference is null"); return false; } + return AssetReference.ReleaseByTag(assetTag); } @@ -543,6 +591,7 @@ namespace TEngine Log.Fatal($"Release Failed => {this}.AssetReference is null"); return false; } + return AssetReference.Release(handle); } @@ -558,6 +607,7 @@ namespace TEngine Log.Fatal($"Release Failed => {this}.AssetReference is null"); return false; } + return AssetReference.Release(address); } @@ -574,6 +624,7 @@ namespace TEngine Log.Fatal($"LoadAsset Failed => {this}.AssetReference is null"); return default; } + return AssetReference.LoadAsset(assetName); } @@ -591,6 +642,7 @@ namespace TEngine Log.Fatal($"LoadAsset Failed => {this}.AssetReference is null"); return default; } + return AssetReference.LoadAsset(assetName, parentTrans); } @@ -608,6 +660,7 @@ namespace TEngine Log.Fatal($"LoadAssetAsync Failed => {this}.AssetReference is null"); return default; } + return await AssetReference.LoadAssetAsync(assetName, cancellationToken); } @@ -624,8 +677,10 @@ namespace TEngine Log.Fatal($"LoadAssetAsync Failed => {this}.AssetReference is null"); return default; } + return await AssetReference.LoadGameObjectAsync(assetName, cancellationToken); } + #endregion } } \ No newline at end of file diff --git a/Assets/TEngine/Runtime/GameFramework/UI/UIWidget.cs b/Assets/TEngine/Runtime/GameFramework/UI/UIWidget.cs index 493c05af..65f1ccd9 100644 --- a/Assets/TEngine/Runtime/GameFramework/UI/UIWidget.cs +++ b/Assets/TEngine/Runtime/GameFramework/UI/UIWidget.cs @@ -3,13 +3,13 @@ using UnityEngine; namespace TEngine { - public abstract class UIWidget:UIBase,IUIBehaviour + public abstract class UIWidget : UIBase, IUIBehaviour { /// /// 窗口组件的实例资源对象。 /// public override GameObject gameObject { protected set; get; } - + /// /// 窗口组件矩阵位置组件。 /// @@ -20,12 +20,12 @@ namespace TEngine /// // ReSharper disable once InconsistentNaming public string name { private set; get; } = nameof(UIWidget); - + /// /// UI类型。 /// public override UIBaseType BaseType => UIBaseType.Widget; - + /// /// 所属的窗口。 /// @@ -47,14 +47,14 @@ namespace TEngine return null; } } - + internal bool InternalUpdate() { if (!IsPrepare) { return false; } - + List listNextUpdateChild = null; if (ListChild != null && ListChild.Count > 0) { @@ -94,7 +94,7 @@ namespace TEngine } } - if (!updateListValid) + if (!updateListValid) { m_updateListValid = true; } @@ -114,12 +114,14 @@ namespace TEngine OnUpdate(); needUpdate = true; } + TProfiler.EndSample(); - + return needUpdate; } #region Create + /// /// 创建窗口内嵌的界面。 /// @@ -131,7 +133,7 @@ namespace TEngine { return CreateImp(parentUI, widgetRoot, false, visible); } - + /// /// 根据资源名创建 /// @@ -147,29 +149,33 @@ namespace TEngine { return false; } + if (!Create(parentUI, goInst, visible)) { return false; } + goInst.transform.localScale = Vector3.one; goInst.transform.localPosition = Vector3.zero; return true; } - + /// /// 根据prefab或者模版来创建新的 widget。 + /// 存在父物体得资源故不需要异步加载。 /// - /// - /// - /// - /// - /// + /// 父物体UI。 + /// 实例化预制体。 + /// 实例化父节点。 + /// 是否可见。 + /// 是否创建成功。 public bool CreateByPrefab(UIBase parentUI, GameObject goPrefab, Transform parentTrans, bool visible = true) { if (parentTrans == null) { parentTrans = parentUI.rectTransform; } + return CreateImp(parentUI, Object.Instantiate(goPrefab, parentTrans), true, visible); } @@ -179,10 +185,12 @@ namespace TEngine { return false; } + if (AssetReference == null) { - AssetReference = AssetReference.BindAssetReference(widgetRoot,parent:parentUI.AssetReference); + AssetReference = AssetReference.BindAssetReference(widgetRoot, parent: parentUI.AssetReference); } + RestChildCanvas(parentUI); parent = parentUI; Parent.ListChild.Add(this); @@ -191,37 +199,41 @@ namespace TEngine RegisterEvent(); OnCreate(); IsPrepare = true; - + if (!visible) { gameObject.SetActive(false); } + return true; } - + protected bool CreateBase(GameObject go, bool bindGo) { if (go == null) { return false; } + rectTransform = go.GetComponent(); gameObject = go; Log.Assert(rectTransform != null, $"{go.name} ui base element need to be RectTransform"); return true; } - + protected void RestChildCanvas(UIBase parentUI) { if (parentUI == null || parentUI.gameObject == null) { return; } + Canvas parentCanvas = parentUI.gameObject.GetComponentInParent(); if (parentCanvas == null) { return; } + if (gameObject != null) { var listCanvas = gameObject.GetComponentsInChildren(true); @@ -232,6 +244,7 @@ namespace TEngine } } } + #endregion #region Destroy @@ -243,6 +256,13 @@ namespace TEngine internal void OnDestroyWidget() { RemoveAllUIEvent(); + + foreach (var uiChild in ListChild) + { + uiChild.OnDestroy(); + uiChild.OnDestroyWidget(); + } + if (Handle != null) { if (AssetReference != null && AssetReference.Parent != null) @@ -250,8 +270,25 @@ namespace TEngine AssetReference.Parent.Release(Handle); } } + + if (gameObject != null) + { + Object.Destroy(gameObject); + } + } + + /// + /// 主动销毁组件。 + /// + public void Destroy() + { + if (parent != null) + { + parent.ListChild.Remove(this); + OnDestroy(); + OnDestroyWidget(); + } } - #endregion }