提供单独销毁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父节点。
/// </summary>
public UIBase Parent => parent;
/// <summary>
/// 自动逸数据集。
/// </summary>
@@ -240,8 +240,10 @@ namespace TEngine
#endregion
#region UIWidget
/// <summary>
/// 创建UIWidget通过父UI位置节点。
/// <remarks>因为资源示例已经存在父物体所以不需要异步。</remarks>
/// </summary>
/// <param name="goPath">父UI位置节点。</param>
/// <param name="visible">是否可见。</param>
@@ -255,12 +257,14 @@ namespace TEngine
{
return CreateWidget<T>(goRootTrans.gameObject, visible);
}
return null;
}
/// <summary>
/// 创建UIWidget通过父UI位置节点。
/// <remarks>因为资源示例已经存在父物体所以不需要异步。</remarks>
/// </summary>
/// <param name="parentTrans"></param>
/// <param name="goPath">父UI位置节点。</param>
@@ -274,11 +278,13 @@ namespace TEngine
{
return CreateWidget<T>(goRootTrans.gameObject, visible);
}
return null;
}
/// <summary>
/// 创建UIWidget通过游戏物体。
/// <remarks>因为资源示例已经存在父物体所以不需要异步。</remarks>
/// </summary>
/// <param name="goRoot">游戏物体。</param>
/// <param name="visible">是否可见。</param>
@@ -291,25 +297,48 @@ namespace TEngine
{
return widget;
}
return null;
}
/// <summary>
/// 创建UIWidget通过资源路径
/// 创建UIWidget通过资源定位地址
/// </summary>
/// <param name="parentTrans">资源父节点。</param>
/// <param name="assetPath">资源路径。</param>
/// <param name="assetLocation">资源定位地址。</param>
/// <param name="visible">是否可见。</param>
/// <typeparam name="T">UIWidget。</typeparam>
/// <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)
{
Log.Fatal($"CreateWidgetByPath Failed => {this}.AssetReference is 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);
}
@@ -344,6 +373,18 @@ namespace TEngine
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>
@@ -354,7 +395,8 @@ namespace TEngine
/// <param name="prefab">资产副本。</param>
/// <param name="assetPath">资产地址。</param>
/// <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)
{
@@ -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
/// <summary>
/// 引用资源数据到资源组内。
/// </summary>
@@ -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<T>(assetName);
}
@@ -591,6 +642,7 @@ namespace TEngine
Log.Fatal($"LoadAsset Failed => {this}.AssetReference is null");
return default;
}
return AssetReference.LoadAsset<T>(assetName, parentTrans);
}
@@ -608,6 +660,7 @@ namespace TEngine
Log.Fatal($"LoadAssetAsync Failed => {this}.AssetReference is null");
return default;
}
return await AssetReference.LoadAssetAsync<T>(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
}
}

View File

@@ -3,13 +3,13 @@ using UnityEngine;
namespace TEngine
{
public abstract class UIWidget:UIBase,IUIBehaviour
public abstract class UIWidget : UIBase, IUIBehaviour
{
/// <summary>
/// 窗口组件的实例资源对象。
/// </summary>
public override GameObject gameObject { protected set; get; }
/// <summary>
/// 窗口组件矩阵位置组件。
/// </summary>
@@ -20,12 +20,12 @@ namespace TEngine
/// </summary>
// ReSharper disable once InconsistentNaming
public string name { private set; get; } = nameof(UIWidget);
/// <summary>
/// UI类型。
/// </summary>
public override UIBaseType BaseType => UIBaseType.Widget;
/// <summary>
/// 所属的窗口。
/// </summary>
@@ -47,14 +47,14 @@ namespace TEngine
return null;
}
}
internal bool InternalUpdate()
{
if (!IsPrepare)
{
return false;
}
List<UIWidget> 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
/// <summary>
/// 创建窗口内嵌的界面。
/// </summary>
@@ -131,7 +133,7 @@ namespace TEngine
{
return CreateImp(parentUI, widgetRoot, false, visible);
}
/// <summary>
/// 根据资源名创建
/// </summary>
@@ -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;
}
/// <summary>
/// 根据prefab或者模版来创建新的 widget。
/// <remarks>存在父物体得资源故不需要异步加载。</remarks>
/// </summary>
/// <param name="parentUI"></param>
/// <param name="goPrefab"></param>
/// <param name="parentTrans"></param>
/// <param name="visible"></param>
/// <returns></returns>
/// <param name="parentUI">父物体UI。</param>
/// <param name="goPrefab">实例化预制体。</param>
/// <param name="parentTrans">实例化父节点。</param>
/// <param name="visible">是否可见。</param>
/// <returns>是否创建成功。</returns>
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<RectTransform>();
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<Canvas>();
if (parentCanvas == null)
{
return;
}
if (gameObject != null)
{
var listCanvas = gameObject.GetComponentsInChildren<Canvas>(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);
}
}
/// <summary>
/// 主动销毁组件。
/// </summary>
public void Destroy()
{
if (parent != null)
{
parent.ListChild.Remove(this);
OnDestroy();
OnDestroyWidget();
}
}
#endregion
}