提供单独销毁UIWidget的接口。增加UIWidget异步创建接口。

提供单独销毁UIWidget的接口。增加UIWidget异步创建接口。
This commit is contained in:
ALEXTANG
2023-08-17 10:59:37 +08:00
parent db935bfb5f
commit 7c74e10857
2 changed files with 122 additions and 30 deletions

View File

@@ -42,7 +42,7 @@ namespace TEngine
/// UI父节点。 /// UI父节点。
/// </summary> /// </summary>
public UIBase Parent => parent; public UIBase Parent => parent;
/// <summary> /// <summary>
/// 自动逸数据集。 /// 自动逸数据集。
/// </summary> /// </summary>
@@ -240,8 +240,10 @@ namespace TEngine
#endregion #endregion
#region UIWidget #region UIWidget
/// <summary> /// <summary>
/// 创建UIWidget通过父UI位置节点。 /// 创建UIWidget通过父UI位置节点。
/// <remarks>因为资源示例已经存在父物体所以不需要异步。</remarks>
/// </summary> /// </summary>
/// <param name="goPath">父UI位置节点。</param> /// <param name="goPath">父UI位置节点。</param>
/// <param name="visible">是否可见。</param> /// <param name="visible">是否可见。</param>
@@ -255,12 +257,14 @@ namespace TEngine
{ {
return CreateWidget<T>(goRootTrans.gameObject, visible); return CreateWidget<T>(goRootTrans.gameObject, visible);
} }
return null; return null;
} }
/// <summary> /// <summary>
/// 创建UIWidget通过父UI位置节点。 /// 创建UIWidget通过父UI位置节点。
/// <remarks>因为资源示例已经存在父物体所以不需要异步。</remarks>
/// </summary> /// </summary>
/// <param name="parentTrans"></param> /// <param name="parentTrans"></param>
/// <param name="goPath">父UI位置节点。</param> /// <param name="goPath">父UI位置节点。</param>
@@ -274,11 +278,13 @@ namespace TEngine
{ {
return CreateWidget<T>(goRootTrans.gameObject, visible); return CreateWidget<T>(goRootTrans.gameObject, visible);
} }
return null; return null;
} }
/// <summary> /// <summary>
/// 创建UIWidget通过游戏物体。 /// 创建UIWidget通过游戏物体。
/// <remarks>因为资源示例已经存在父物体所以不需要异步。</remarks>
/// </summary> /// </summary>
/// <param name="goRoot">游戏物体。</param> /// <param name="goRoot">游戏物体。</param>
/// <param name="visible">是否可见。</param> /// <param name="visible">是否可见。</param>
@@ -291,25 +297,48 @@ namespace TEngine
{ {
return widget; return widget;
} }
return null; return null;
} }
/// <summary> /// <summary>
/// 创建UIWidget通过资源路径 /// 创建UIWidget通过资源定位地址
/// </summary> /// </summary>
/// <param name="parentTrans">资源父节点。</param> /// <param name="parentTrans">资源父节点。</param>
/// <param name="assetPath">资源路径。</param> /// <param name="assetLocation">资源定位地址。</param>
/// <param name="visible">是否可见。</param> /// <param name="visible">是否可见。</param>
/// <typeparam name="T">UIWidget。</typeparam> /// <typeparam name="T">UIWidget。</typeparam>
/// <returns>UIWidget实例。</returns> /// <returns>UIWidget实例。</returns>
public T CreateWidgetByPath<T>(Transform parentTrans, string assetPath, bool visible = true) where T : UIWidget, new() public T CreateWidgetByPath<T>(Transform parentTrans, string assetLocation, bool visible = true) where T : UIWidget, new()
{ {
if (AssetReference == null) if (AssetReference == null)
{ {
Log.Fatal($"CreateWidgetByPath Failed => {this}.AssetReference is null"); Log.Fatal($"CreateWidgetByPath Failed => {this}.AssetReference is null");
return null; return null;
} }
GameObject goInst = AssetReference.LoadAsset<GameObject>(assetPath, parentTrans);
GameObject goInst = AssetReference.LoadAsset<GameObject>(assetLocation, parentTrans);
return CreateWidget<T>(goInst, visible);
}
/// <summary>
/// 创建UIWidget通过资源定位地址。
/// </summary>
/// <param name="parentTrans">资源父节点。</param>
/// <param name="assetLocation">资源定位地址。</param>
/// <param name="visible">是否可见。</param>
/// <typeparam name="T">UIWidget。</typeparam>
/// <returns>UIWidget实例。</returns>
public async UniTask<T> CreateWidgetByPathAsync<T>(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<GameObject>(assetLocation, gameObject.GetCancellationTokenOnDestroy());
goInst.transform.SetParent(parentTrans);
return CreateWidget<T>(goInst, visible); return CreateWidget<T>(goInst, visible);
} }
@@ -344,6 +373,18 @@ namespace TEngine
return CreateWidgetByPath<T>(parentTrans, typeof(T).Name, visible); return CreateWidgetByPath<T>(parentTrans, typeof(T).Name, visible);
} }
/// <summary>
/// 通过UI类型来创建widget。
/// </summary>
/// <param name="parentTrans">资源父节点。</param>
/// <param name="visible">是否可见。</param>
/// <typeparam name="T">UIWidget。</typeparam>
/// <returns>UIWidget实例。</returns>
public async UniTask<T> CreateWidgetByTypeAsync<T>(Transform parentTrans, bool visible = true) where T : UIWidget, new()
{
return await CreateWidgetByPathAsync<T>(parentTrans, typeof(T).Name, visible);
}
/// <summary> /// <summary>
/// 调整图标数量。 /// 调整图标数量。
/// </summary> /// </summary>
@@ -354,7 +395,8 @@ namespace TEngine
/// <param name="prefab">资产副本。</param> /// <param name="prefab">资产副本。</param>
/// <param name="assetPath">资产地址。</param> /// <param name="assetPath">资产地址。</param>
/// <typeparam name="T">图标类型。</typeparam> /// <typeparam name="T">图标类型。</typeparam>
public void AdjustIconNum<T>(List<T> listIcon, int number, Transform parentTrans, GameObject prefab = null, string assetPath = "") where T : UIWidget, new() public void AdjustIconNum<T>(List<T> listIcon, int number, Transform parentTrans, GameObject prefab = null, string assetPath = "")
where T : UIWidget, new()
{ {
if (listIcon == null) if (listIcon == null)
{ {
@@ -475,14 +517,17 @@ namespace TEngine
icon.OnDestroy(); icon.OnDestroy();
icon.OnDestroyWidget(); icon.OnDestroyWidget();
ListChild.Remove(icon); ListChild.Remove(icon);
UnityEngine.Object.Destroy(icon.gameObject); if (icon.gameObject != null)
{
UnityEngine.Object.Destroy(icon.gameObject);
}
} }
} }
#endregion #endregion
#region AssetRefrence Methods #region AssetRefrence Methods
/// <summary> /// <summary>
/// 引用资源数据到资源组内。 /// 引用资源数据到资源组内。
/// </summary> /// </summary>
@@ -496,6 +541,7 @@ namespace TEngine
Log.Fatal($"Reference Failed => {this}.AssetReference is null"); Log.Fatal($"Reference Failed => {this}.AssetReference is null");
return false; return false;
} }
return AssetReference.Reference(handle, assetTag); return AssetReference.Reference(handle, assetTag);
} }
@@ -513,6 +559,7 @@ namespace TEngine
Log.Fatal($"Reference Failed => {this}.AssetReference is null"); Log.Fatal($"Reference Failed => {this}.AssetReference is null");
return false; return false;
} }
return AssetReference.Reference(address, handle, assetTag); return AssetReference.Reference(address, handle, assetTag);
} }
@@ -528,6 +575,7 @@ namespace TEngine
Log.Fatal($"Release Failed => {this}.AssetReference is null"); Log.Fatal($"Release Failed => {this}.AssetReference is null");
return false; return false;
} }
return AssetReference.ReleaseByTag(assetTag); return AssetReference.ReleaseByTag(assetTag);
} }
@@ -543,6 +591,7 @@ namespace TEngine
Log.Fatal($"Release Failed => {this}.AssetReference is null"); Log.Fatal($"Release Failed => {this}.AssetReference is null");
return false; return false;
} }
return AssetReference.Release(handle); return AssetReference.Release(handle);
} }
@@ -558,6 +607,7 @@ namespace TEngine
Log.Fatal($"Release Failed => {this}.AssetReference is null"); Log.Fatal($"Release Failed => {this}.AssetReference is null");
return false; return false;
} }
return AssetReference.Release(address); return AssetReference.Release(address);
} }
@@ -574,6 +624,7 @@ namespace TEngine
Log.Fatal($"LoadAsset Failed => {this}.AssetReference is null"); Log.Fatal($"LoadAsset Failed => {this}.AssetReference is null");
return default; return default;
} }
return AssetReference.LoadAsset<T>(assetName); return AssetReference.LoadAsset<T>(assetName);
} }
@@ -591,6 +642,7 @@ namespace TEngine
Log.Fatal($"LoadAsset Failed => {this}.AssetReference is null"); Log.Fatal($"LoadAsset Failed => {this}.AssetReference is null");
return default; return default;
} }
return AssetReference.LoadAsset<T>(assetName, parentTrans); return AssetReference.LoadAsset<T>(assetName, parentTrans);
} }
@@ -608,6 +660,7 @@ namespace TEngine
Log.Fatal($"LoadAssetAsync Failed => {this}.AssetReference is null"); Log.Fatal($"LoadAssetAsync Failed => {this}.AssetReference is null");
return default; return default;
} }
return await AssetReference.LoadAssetAsync<T>(assetName, cancellationToken); return await AssetReference.LoadAssetAsync<T>(assetName, cancellationToken);
} }
@@ -624,8 +677,10 @@ namespace TEngine
Log.Fatal($"LoadAssetAsync Failed => {this}.AssetReference is null"); Log.Fatal($"LoadAssetAsync Failed => {this}.AssetReference is null");
return default; return default;
} }
return await AssetReference.LoadGameObjectAsync(assetName, cancellationToken); return await AssetReference.LoadGameObjectAsync(assetName, cancellationToken);
} }
#endregion #endregion
} }
} }

View File

@@ -3,13 +3,13 @@ using UnityEngine;
namespace TEngine namespace TEngine
{ {
public abstract class UIWidget:UIBase,IUIBehaviour public abstract class UIWidget : UIBase, IUIBehaviour
{ {
/// <summary> /// <summary>
/// 窗口组件的实例资源对象。 /// 窗口组件的实例资源对象。
/// </summary> /// </summary>
public override GameObject gameObject { protected set; get; } public override GameObject gameObject { protected set; get; }
/// <summary> /// <summary>
/// 窗口组件矩阵位置组件。 /// 窗口组件矩阵位置组件。
/// </summary> /// </summary>
@@ -20,12 +20,12 @@ namespace TEngine
/// </summary> /// </summary>
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
public string name { private set; get; } = nameof(UIWidget); public string name { private set; get; } = nameof(UIWidget);
/// <summary> /// <summary>
/// UI类型。 /// UI类型。
/// </summary> /// </summary>
public override UIBaseType BaseType => UIBaseType.Widget; public override UIBaseType BaseType => UIBaseType.Widget;
/// <summary> /// <summary>
/// 所属的窗口。 /// 所属的窗口。
/// </summary> /// </summary>
@@ -47,14 +47,14 @@ namespace TEngine
return null; return null;
} }
} }
internal bool InternalUpdate() internal bool InternalUpdate()
{ {
if (!IsPrepare) if (!IsPrepare)
{ {
return false; return false;
} }
List<UIWidget> listNextUpdateChild = null; List<UIWidget> listNextUpdateChild = null;
if (ListChild != null && ListChild.Count > 0) if (ListChild != null && ListChild.Count > 0)
{ {
@@ -94,7 +94,7 @@ namespace TEngine
} }
} }
if (!updateListValid) if (!updateListValid)
{ {
m_updateListValid = true; m_updateListValid = true;
} }
@@ -114,12 +114,14 @@ namespace TEngine
OnUpdate(); OnUpdate();
needUpdate = true; needUpdate = true;
} }
TProfiler.EndSample(); TProfiler.EndSample();
return needUpdate; return needUpdate;
} }
#region Create #region Create
/// <summary> /// <summary>
/// 创建窗口内嵌的界面。 /// 创建窗口内嵌的界面。
/// </summary> /// </summary>
@@ -131,7 +133,7 @@ namespace TEngine
{ {
return CreateImp(parentUI, widgetRoot, false, visible); return CreateImp(parentUI, widgetRoot, false, visible);
} }
/// <summary> /// <summary>
/// 根据资源名创建 /// 根据资源名创建
/// </summary> /// </summary>
@@ -147,29 +149,33 @@ namespace TEngine
{ {
return false; return false;
} }
if (!Create(parentUI, goInst, visible)) if (!Create(parentUI, goInst, visible))
{ {
return false; return false;
} }
goInst.transform.localScale = Vector3.one; goInst.transform.localScale = Vector3.one;
goInst.transform.localPosition = Vector3.zero; goInst.transform.localPosition = Vector3.zero;
return true; return true;
} }
/// <summary> /// <summary>
/// 根据prefab或者模版来创建新的 widget。 /// 根据prefab或者模版来创建新的 widget。
/// <remarks>存在父物体得资源故不需要异步加载。</remarks>
/// </summary> /// </summary>
/// <param name="parentUI"></param> /// <param name="parentUI">父物体UI。</param>
/// <param name="goPrefab"></param> /// <param name="goPrefab">实例化预制体。</param>
/// <param name="parentTrans"></param> /// <param name="parentTrans">实例化父节点。</param>
/// <param name="visible"></param> /// <param name="visible">是否可见。</param>
/// <returns></returns> /// <returns>是否创建成功。</returns>
public bool CreateByPrefab(UIBase parentUI, GameObject goPrefab, Transform parentTrans, bool visible = true) public bool CreateByPrefab(UIBase parentUI, GameObject goPrefab, Transform parentTrans, bool visible = true)
{ {
if (parentTrans == null) if (parentTrans == null)
{ {
parentTrans = parentUI.rectTransform; parentTrans = parentUI.rectTransform;
} }
return CreateImp(parentUI, Object.Instantiate(goPrefab, parentTrans), true, visible); return CreateImp(parentUI, Object.Instantiate(goPrefab, parentTrans), true, visible);
} }
@@ -179,10 +185,12 @@ namespace TEngine
{ {
return false; return false;
} }
if (AssetReference == null) if (AssetReference == null)
{ {
AssetReference = AssetReference.BindAssetReference(widgetRoot,parent:parentUI.AssetReference); AssetReference = AssetReference.BindAssetReference(widgetRoot, parent: parentUI.AssetReference);
} }
RestChildCanvas(parentUI); RestChildCanvas(parentUI);
parent = parentUI; parent = parentUI;
Parent.ListChild.Add(this); Parent.ListChild.Add(this);
@@ -191,37 +199,41 @@ namespace TEngine
RegisterEvent(); RegisterEvent();
OnCreate(); OnCreate();
IsPrepare = true; IsPrepare = true;
if (!visible) if (!visible)
{ {
gameObject.SetActive(false); gameObject.SetActive(false);
} }
return true; return true;
} }
protected bool CreateBase(GameObject go, bool bindGo) protected bool CreateBase(GameObject go, bool bindGo)
{ {
if (go == null) if (go == null)
{ {
return false; return false;
} }
rectTransform = go.GetComponent<RectTransform>(); rectTransform = go.GetComponent<RectTransform>();
gameObject = go; gameObject = go;
Log.Assert(rectTransform != null, $"{go.name} ui base element need to be RectTransform"); Log.Assert(rectTransform != null, $"{go.name} ui base element need to be RectTransform");
return true; return true;
} }
protected void RestChildCanvas(UIBase parentUI) protected void RestChildCanvas(UIBase parentUI)
{ {
if (parentUI == null || parentUI.gameObject == null) if (parentUI == null || parentUI.gameObject == null)
{ {
return; return;
} }
Canvas parentCanvas = parentUI.gameObject.GetComponentInParent<Canvas>(); Canvas parentCanvas = parentUI.gameObject.GetComponentInParent<Canvas>();
if (parentCanvas == null) if (parentCanvas == null)
{ {
return; return;
} }
if (gameObject != null) if (gameObject != null)
{ {
var listCanvas = gameObject.GetComponentsInChildren<Canvas>(true); var listCanvas = gameObject.GetComponentsInChildren<Canvas>(true);
@@ -232,6 +244,7 @@ namespace TEngine
} }
} }
} }
#endregion #endregion
#region Destroy #region Destroy
@@ -243,6 +256,13 @@ namespace TEngine
internal void OnDestroyWidget() internal void OnDestroyWidget()
{ {
RemoveAllUIEvent(); RemoveAllUIEvent();
foreach (var uiChild in ListChild)
{
uiChild.OnDestroy();
uiChild.OnDestroyWidget();
}
if (Handle != null) if (Handle != null)
{ {
if (AssetReference != null && AssetReference.Parent != null) if (AssetReference != null && AssetReference.Parent != null)
@@ -250,8 +270,25 @@ namespace TEngine
AssetReference.Parent.Release(Handle); AssetReference.Parent.Release(Handle);
} }
} }
if (gameObject != null)
{
Object.Destroy(gameObject);
}
}
/// <summary>
/// 主动销毁组件。
/// </summary>
public void Destroy()
{
if (parent != null)
{
parent.ListChild.Remove(this);
OnDestroy();
OnDestroyWidget();
}
} }
#endregion #endregion
} }