优化UI模块 同步异步加载

This commit is contained in:
陈思海 2025-11-13 17:46:20 +08:00
parent 110c3451ea
commit 69699074de
11 changed files with 208 additions and 66 deletions

Binary file not shown.

View File

@ -17,7 +17,7 @@ namespace AlicizaX.UI.Runtime
ResourceModule = ModuleSystem.GetModule<IResourceModule>(); ResourceModule = ModuleSystem.GetModule<IResourceModule>();
} }
public static async UniTask<T> CreateUIHolder<T>(Transform parent) where T : UIHolderObjectBase public static async UniTask<T> CreateUIHolderAsync<T>(Transform parent) where T : UIHolderObjectBase
{ {
if (UIResRegistry.TryGet(typeof(T).TypeHandle, out UIResRegistry.UIResInfo resInfo)) if (UIResRegistry.TryGet(typeof(T).TypeHandle, out UIResRegistry.UIResInfo resInfo))
{ {
@ -29,6 +29,19 @@ namespace AlicizaX.UI.Runtime
return null; return null;
} }
public static T CreateUIHolderSync<T>(Transform parent) where T : UIHolderObjectBase
{
if (UIResRegistry.TryGet(typeof(T).TypeHandle, out UIResRegistry.UIResInfo resInfo))
{
GameObject obj = LoadUIResourcesSync(resInfo, parent);
return obj.GetComponent<T>();
}
return null;
}
internal static async UniTask<GameObject> LoadUIResourcesAsync(UIResRegistry.UIResInfo resInfo, Transform parent) internal static async UniTask<GameObject> LoadUIResourcesAsync(UIResRegistry.UIResInfo resInfo, Transform parent)
{ {
return resInfo.LoadType == EUIResLoadType.AssetBundle return resInfo.LoadType == EUIResLoadType.AssetBundle
@ -36,24 +49,39 @@ namespace AlicizaX.UI.Runtime
: await InstantiateResourceAsync(resInfo.Location, parent); : await InstantiateResourceAsync(resInfo.Location, parent);
} }
internal static async UniTask CreateUIResource(UIMetadata meta, Transform parent, UIBase owner = null) internal static GameObject LoadUIResourcesSync(UIResRegistry.UIResInfo resInfo, Transform parent)
{
return resInfo.LoadType == EUIResLoadType.AssetBundle
? ResourceModule.LoadGameObject(resInfo.Location, parent)
: InstantiateResourceSync(resInfo.Location, parent);
}
internal static async UniTask CreateUIResourceAsync(UIMetadata meta, Transform parent, UIBase owner = null)
{ {
if (meta.State != UIState.CreatedUI) return; if (meta.State != UIState.CreatedUI) return;
GameObject obj = await LoadUIResourcesAsync(meta.ResInfo, parent); GameObject obj = await LoadUIResourcesAsync(meta.ResInfo, parent);
ValidateAndBind(meta, obj, owner); ValidateAndBind(meta, obj, owner);
} }
internal static void LoadUIResourcesSync(UIMetadata meta, Transform parent, UIBase owner = null) internal static void CreateUIResourceSync(UIMetadata meta, Transform parent, UIBase owner = null)
{ {
if (meta.State != UIState.CreatedUI) return; if (meta.State != UIState.CreatedUI) return;
GameObject obj = LoadUIResourcesSync(meta.ResInfo, parent);
GameObject obj = meta.ResInfo.LoadType == EUIResLoadType.AssetBundle
? ResourceModule.LoadGameObject(meta.ResInfo.Location, parent)
: Object.Instantiate(Resources.Load<GameObject>(meta.ResInfo.Location), parent);
ValidateAndBind(meta, obj, owner); ValidateAndBind(meta, obj, owner);
} }
private static async UniTask<GameObject> InstantiateResourceAsync(string location, Transform parent)
{
GameObject prefab = (GameObject)await Resources.LoadAsync<GameObject>(location);
return Object.Instantiate(prefab, parent);
}
private static GameObject InstantiateResourceSync(string location, Transform parent)
{
GameObject prefab = Resources.Load<GameObject>(location);
return Object.Instantiate(prefab, parent);
}
private static void ValidateAndBind(UIMetadata meta, GameObject holderObject, UIBase owner) private static void ValidateAndBind(UIMetadata meta, GameObject holderObject, UIBase owner)
{ {
@ -68,11 +96,5 @@ namespace AlicizaX.UI.Runtime
meta.View?.BindUIHolder(holder, owner); meta.View?.BindUIHolder(holder, owner);
} }
private static async UniTask<GameObject> InstantiateResourceAsync(string location, Transform parent)
{
GameObject prefab = (GameObject)await Resources.LoadAsync<GameObject>(location);
return Object.Instantiate(prefab, parent);
}
} }
} }

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using UnityEngine.PlayerLoop;
namespace AlicizaX.UI.Runtime namespace AlicizaX.UI.Runtime
{ {
@ -16,14 +17,16 @@ namespace AlicizaX.UI.Runtime
public readonly int UILayer; public readonly int UILayer;
public readonly bool FullScreen; public readonly bool FullScreen;
public readonly int CacheTime; public readonly int CacheTime;
public readonly bool NeedUpdate;
public UIMetaInfo(RuntimeTypeHandle runtimeTypeHandle, RuntimeTypeHandle holderRuntimeTypeHandle, UILayer windowLayer, bool fullScreen, int cacheTime) public UIMetaInfo(RuntimeTypeHandle runtimeTypeHandle, RuntimeTypeHandle holderRuntimeTypeHandle, UILayer windowLayer, bool fullScreen, int cacheTime, bool needUpdate)
{ {
RuntimeTypeHandle = runtimeTypeHandle; RuntimeTypeHandle = runtimeTypeHandle;
HolderRuntimeTypeHandle = holderRuntimeTypeHandle; HolderRuntimeTypeHandle = holderRuntimeTypeHandle;
UILayer = (int)windowLayer; UILayer = (int)windowLayer;
FullScreen = fullScreen; FullScreen = fullScreen;
CacheTime = cacheTime; CacheTime = cacheTime;
NeedUpdate = needUpdate;
} }
} }
@ -31,11 +34,11 @@ namespace AlicizaX.UI.Runtime
private static readonly Dictionary<string, RuntimeTypeHandle> _stringHandleMap = new(); private static readonly Dictionary<string, RuntimeTypeHandle> _stringHandleMap = new();
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Register(Type uiType, Type holderType, UILayer layer = UILayer.UI, bool fullScreen = false, int cacheTime = 0) public static void Register(Type uiType, Type holderType, UILayer layer = UILayer.UI, bool fullScreen = false, int cacheTime = 0, bool needUpdate = false)
{ {
var holderHandle = holderType.TypeHandle; var holderHandle = holderType.TypeHandle;
var uiHandle = uiType.TypeHandle; var uiHandle = uiType.TypeHandle;
_typeHandleMap[uiHandle] = new UIMetaInfo(uiHandle, holderHandle, layer, fullScreen, cacheTime); _typeHandleMap[uiHandle] = new UIMetaInfo(uiHandle, holderHandle, layer, fullScreen, cacheTime, needUpdate);
_stringHandleMap[uiType.Name] = uiHandle; _stringHandleMap[uiType.Name] = uiHandle;
} }
@ -80,21 +83,25 @@ namespace AlicizaX.UI.Runtime
UILayer layer = UILayer.UI; UILayer layer = UILayer.UI;
bool fullScreen = false; bool fullScreen = false;
int cacheTime = 0; int cacheTime = 0;
bool needUpdate = false;
var cad = CustomAttributeData.GetCustomAttributes(uiType) var windowAttribute = CustomAttributeData.GetCustomAttributes(uiType)
.FirstOrDefault(a => a.AttributeType.Name == nameof(WindowAttribute)); .FirstOrDefault(a => a.AttributeType.Name == nameof(WindowAttribute));
var uiUpdateAttribute = CustomAttributeData.GetCustomAttributes(uiType)
if (cad != null) .FirstOrDefault(a => a.AttributeType.Name == nameof(UIUpdateAttribute));
if (windowAttribute != null)
{ {
var args = cad.ConstructorArguments; var args = windowAttribute.ConstructorArguments;
if (args.Count > 0) layer = (UILayer)(args[0].Value ?? UILayer.UI); if (args.Count > 0) layer = (UILayer)(args[0].Value ?? UILayer.UI);
if (args.Count > 1) fullScreen = (bool)(args[1].Value ?? false); if (args.Count > 1) fullScreen = (bool)(args[1].Value ?? false);
if (args.Count > 2) cacheTime = (int)(args[2].Value ?? 0); if (args.Count > 2) cacheTime = (int)(args[2].Value ?? 0);
} }
needUpdate = uiUpdateAttribute != null;
if (holderType != null) if (holderType != null)
{ {
Register(uiType, holderType, layer, fullScreen, cacheTime); Register(uiType, holderType, layer, fullScreen, cacheTime, needUpdate);
info = _typeHandleMap[uiType.TypeHandle]; info = _typeHandleMap[uiType.TypeHandle];
return true; return true;
} }

View File

@ -3,7 +3,6 @@ using UnityEngine;
namespace AlicizaX.UI.Runtime namespace AlicizaX.UI.Runtime
{ {
[AttributeUsage(AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Class)]
public class WindowAttribute : Attribute public class WindowAttribute : Attribute
{ {
@ -36,6 +35,15 @@ namespace AlicizaX.UI.Runtime
} }
} }
[AttributeUsage(AttributeTargets.Class)]
public class UIUpdateAttribute : Attribute
{
public UIUpdateAttribute()
{
}
}
[AttributeUsage(AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Class)]
public class UIResAttribute : Attribute public class UIResAttribute : Attribute
{ {
@ -49,7 +57,7 @@ namespace AlicizaX.UI.Runtime
} }
} }
public enum EUIResLoadType:byte public enum EUIResLoadType : byte
{ {
Resources, Resources,
AssetBundle AssetBundle

View File

@ -1,24 +1,78 @@
using System; using System;
using AlicizaX.Resource.Runtime;
using AlicizaX;
using AlicizaX.Timer.Runtime; using AlicizaX.Timer.Runtime;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using UnityEngine; using UnityEngine;
namespace AlicizaX.UI.Runtime namespace AlicizaX.UI.Runtime
{ {
/// <summary>
/// UI 模块接口:负责 UI 的创建、显示、关闭与查询。
/// 支持异步与同步(预加载)两种打开方式。
/// </summary>
public interface IUIModule : IModule, IModuleUpdate public interface IUIModule : IModule, IModuleUpdate
{ {
void Initlize(Transform root,bool isOrthographic); /// <summary>
/// 初始化 UI 模块。
/// </summary>
/// <param name="root">UI 根节点(通常为 Canvas 根)</param>
/// <param name="isOrthographic">摄像机是否正交模式</param>
void Initialize(Transform root, bool isOrthographic);
/// <summary>
/// UI 摄像机
/// </summary>
Camera UICamera { get; set; } Camera UICamera { get; set; }
/// <summary>
/// UI 根节点
/// </summary>
Transform UICanvasRoot { get; set; } Transform UICanvasRoot { get; set; }
UniTask<UIBase> ShowUI<T>(params System.Object[] userDatas) where T : UIBase;
// ───────────────────────────────────────────────
// Show 系列:异步为主,同步为辅
// ───────────────────────────────────────────────
/// <summary>
/// 异步显示 UI推荐方式
/// </summary>
UniTask<T> ShowUI<T>(params object[] userDatas) where T : UIBase;
/// <summary>
/// 异步显示 UI使用字符串类型名
/// </summary>
UniTask<UIBase>? ShowUI(string type, params object[] userDatas); UniTask<UIBase>? ShowUI(string type, params object[] userDatas);
UniTask<T> ShowUIAsync<T>(params System.Object[] userDatas) where T : UIBase;
/// <summary>
/// 同步显示 UI仅限资源已预加载时使用避免死锁
/// </summary>
T ShowUISync<T>(params object[] userDatas) where T : UIBase;
// ───────────────────────────────────────────────
// Close / Get 系列
// ───────────────────────────────────────────────
/// <summary>
/// 关闭指定类型 UI。
/// </summary>
void CloseUI<T>(bool force = false) where T : UIBase; void CloseUI<T>(bool force = false) where T : UIBase;
/// <summary>
/// 关闭指定类型 UI。
/// </summary>
void CloseUI(RuntimeTypeHandle handle, bool force = false);
/// <summary>
/// 获取当前已打开的指定类型 UI。
/// </summary>
T GetUI<T>() where T : UIBase; T GetUI<T>() where T : UIBase;
void CloseUI(RuntimeTypeHandle handle, bool force = false); // ───────────────────────────────────────────────
// 内部注入
// ───────────────────────────────────────────────
/// <summary>
/// 由框架内部注入计时模块。
/// </summary>
protected internal void SetTimerManager(ITimerModule timerModule); protected internal void SetTimerManager(ITimerModule timerModule);
} }
} }

View File

@ -21,7 +21,7 @@ namespace AlicizaX.UI.Runtime
private RectTransform UICacheLayer; private RectTransform UICacheLayer;
private bool _isOrthographic; private bool _isOrthographic;
public void Initlize(Transform root, bool isOrthographic) public void Initialize(Transform root, bool isOrthographic)
{ {
UIRoot = root; UIRoot = root;
Object.DontDestroyOnLoad(root.gameObject); Object.DontDestroyOnLoad(root.gameObject);

View File

@ -22,11 +22,22 @@ namespace AlicizaX.UI.Runtime
{ {
private readonly LayerData[] _openUI = new LayerData[(int)UILayer.All]; private readonly LayerData[] _openUI = new LayerData[(int)UILayer.All];
private async UniTask<UIBase> ShowUIImplAsync(UIMetadata meta, params object[] userDatas) private async UniTask<UIBase> ShowUIImplAsync(UIMetadata metaInfo, params object[] userDatas)
{ {
var metaInfo = GetOrCreateMeta(meta); CreateMetaUI(metaInfo);
await UIHolderFactory.CreateUIResource(metaInfo, UICacheLayer); await UIHolderFactory.CreateUIResourceAsync(metaInfo, UICacheLayer);
return await FinalizeShow(metaInfo, userDatas); FinalizeShow(metaInfo, userDatas);
await UpdateVisualState(metaInfo);
return metaInfo.View;
}
private UIBase ShowUIImplSync(UIMetadata metaInfo, params object[] userDatas)
{
CreateMetaUI(metaInfo);
UIHolderFactory.CreateUIResourceSync(metaInfo, UICacheLayer);
FinalizeShow(metaInfo, userDatas);
UpdateVisualState(metaInfo).Forget();
return metaInfo.View;
} }
private async UniTask CloseUIImpl(UIMetadata meta, bool force) private async UniTask CloseUIImpl(UIMetadata meta, bool force)
@ -35,6 +46,7 @@ namespace AlicizaX.UI.Runtime
{ {
return; return;
} }
await meta.View.InternalClose(); await meta.View.InternalClose();
Pop(meta); Pop(meta);
SortWindowVisible(meta.MetaInfo.UILayer); SortWindowVisible(meta.MetaInfo.UILayer);
@ -49,14 +61,13 @@ namespace AlicizaX.UI.Runtime
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private UIMetadata GetOrCreateMeta(UIMetadata meta) private void CreateMetaUI(UIMetadata meta)
{ {
if (meta.State == UIState.Uninitialized) meta.CreateUI(); if (meta.State == UIState.Uninitialized) meta.CreateUI();
return meta;
} }
private async UniTask<UIBase> FinalizeShow(UIMetadata meta, object[] userDatas) private void FinalizeShow(UIMetadata meta, object[] userDatas)
{ {
if (meta.InCache) if (meta.InCache)
{ {
@ -77,8 +88,6 @@ namespace AlicizaX.UI.Runtime
} }
meta.View.RefreshParams(userDatas); meta.View.RefreshParams(userDatas);
await UpdateVisualState(meta);
return meta.View;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@ -19,12 +19,11 @@ namespace AlicizaX.UI.Runtime
void IModuleUpdate.Update(float elapseSeconds, float realElapseSeconds) void IModuleUpdate.Update(float elapseSeconds, float realElapseSeconds)
{ {
// 遍历所有层级
for (int layerIndex = 0; layerIndex < _openUI.Length; layerIndex++) for (int layerIndex = 0; layerIndex < _openUI.Length; layerIndex++)
{ {
var layer = _openUI[layerIndex]; var layer = _openUI[layerIndex];
int count = layer.OrderList.Count; int count = layer.OrderList.Count;
if (count == 0) continue; // 跳过空层级 if (count == 0) continue;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
if (layer.OrderList.Count != count) if (layer.OrderList.Count != count)
@ -33,6 +32,7 @@ namespace AlicizaX.UI.Runtime
} }
var window = layer.OrderList[i]; var window = layer.OrderList[i];
if (window.MetaInfo.NeedUpdate)
window.View.InternalUpdate(); window.View.InternalUpdate();
} }
} }
@ -50,13 +50,12 @@ namespace AlicizaX.UI.Runtime
return null; return null;
} }
public T ShowUISync<T>(params object[] userDatas) where T : UIBase
public UniTask<UIBase> ShowUI<T>(params System.Object[] userDatas) where T : UIBase
{ {
return ShowUI(MetaTypeCache<T>.Metadata, userDatas); return (T)ShowUIImplSync(MetaTypeCache<T>.Metadata, userDatas);
} }
public async UniTask<T> ShowUIAsync<T>(params System.Object[] userDatas) where T : UIBase public async UniTask<T> ShowUI<T>(params System.Object[] userDatas) where T : UIBase
{ {
return (T)await ShowUIAsync(MetaTypeCache<T>.Metadata, userDatas); return (T)await ShowUIAsync(MetaTypeCache<T>.Metadata, userDatas);
} }
@ -69,7 +68,7 @@ namespace AlicizaX.UI.Runtime
public T GetUI<T>() where T : UIBase public T GetUI<T>() where T : UIBase
{ {
return (T)GetUI(MetaTypeCache<T>.Metadata); return (T)GetUIImpl(MetaTypeCache<T>.Metadata);
} }
@ -93,11 +92,6 @@ namespace AlicizaX.UI.Runtime
} }
} }
private UIBase GetUI(UIMetadata meta)
{
return (UIBase)GetUIImpl(meta);
}
void IUIModule.SetTimerManager(ITimerModule timerModule) void IUIModule.SetTimerManager(ITimerModule timerModule)
{ {

View File

@ -17,7 +17,7 @@ namespace AlicizaX.UI.Runtime
var values = _children.Values; var values = _children.Values;
foreach (var meta in values) foreach (var meta in values)
{ {
if (meta.View.State == UIState.Opened) if (meta.View.State == UIState.Opened && meta.MetaInfo.NeedUpdate)
{ {
meta.View.InternalUpdate(); meta.View.InternalUpdate();
} }
@ -43,7 +43,7 @@ namespace AlicizaX.UI.Runtime
} }
finally finally
{ {
ArrayPool<UIMetadata>.Shared.Return(temp); ArrayPool<UIMetadata>.Shared.Return(temp, true);
} }
_children.Clear(); _children.Clear();
@ -61,28 +61,40 @@ namespace AlicizaX.UI.Runtime
} }
} }
internal async UniTask<UIBase> CreateWidget(UIMetadata metadata, Transform parent, bool visible) internal async UniTask<UIBase> CreateWidgetUIAsync(UIMetadata metadata, Transform parent, bool visible)
{ {
metadata.CreateUI(); metadata.CreateUI();
await UIHolderFactory.CreateUIResource(metadata, parent, this); await UIHolderFactory.CreateUIResourceAsync(metadata, parent, this);
await ProcessWidget(metadata, visible); await ProcessWidget(metadata, visible);
return (UIBase)metadata.View; return (UIBase)metadata.View;
} }
protected async UniTask<UIBase> CreateWidget(string typeName, Transform parent, bool visible = true) internal UIBase CreateWidgetUISync(UIMetadata metadata, Transform parent, bool visible)
{
metadata.CreateUI();
UIHolderFactory.CreateUIResourceSync(metadata, parent, this);
ProcessWidget(metadata, visible).Forget();
return (UIBase)metadata.View;
}
#region CreateWidget
#region Async
protected async UniTask<UIBase> CreateWidgetAsync(string typeName, Transform parent, bool visible = true)
{ {
UIMetaRegistry.TryGet(typeName, out var metaRegistry); UIMetaRegistry.TryGet(typeName, out var metaRegistry);
UIMetadata metadata = UIMetadataFactory.GetMetadata(metaRegistry.RuntimeTypeHandle); UIMetadata metadata = UIMetadataFactory.GetMetadata(metaRegistry.RuntimeTypeHandle);
return await CreateWidget(metadata, parent, visible); return await CreateWidgetUIAsync(metadata, parent, visible);
} }
protected async UniTask<T> CreateWidget<T>(Transform parent, bool visible = true) where T : UIBase protected async UniTask<T> CreateWidgetAsync<T>(Transform parent, bool visible = true) where T : UIBase
{ {
UIMetadata metadata = MetaTypeCache<T>.Metadata; UIMetadata metadata = MetaTypeCache<T>.Metadata;
return (T)await CreateWidget(metadata, parent, visible); return (T)await CreateWidgetUIAsync(metadata, parent, visible);
} }
protected async UniTask<T> CreateWidget<T>(UIHolderObjectBase holder) where T : UIBase protected async UniTask<T> CreateWidgetAsync<T>(UIHolderObjectBase holder) where T : UIBase
{ {
UIMetadata metadata = MetaTypeCache<T>.Metadata; UIMetadata metadata = MetaTypeCache<T>.Metadata;
metadata.CreateUI(); metadata.CreateUI();
@ -92,9 +104,42 @@ namespace AlicizaX.UI.Runtime
return (T)widget; return (T)widget;
} }
#endregion
#region Sync
protected UIBase CreateWidgetSync(string typeName, Transform parent, bool visible = true)
{
UIMetaRegistry.TryGet(typeName, out var metaRegistry);
UIMetadata metadata = UIMetadataFactory.GetMetadata(metaRegistry.RuntimeTypeHandle);
return CreateWidgetUISync(metadata, parent, visible);
}
protected T CreateWidgetSync<T>(Transform parent, bool visible = true) where T : UIBase
{
UIMetadata metadata = MetaTypeCache<T>.Metadata;
return (T)CreateWidgetUISync(metadata, parent, visible);
}
protected T CreateWidgetSync<T>(UIHolderObjectBase holder) where T : UIBase
{
UIMetadata metadata = MetaTypeCache<T>.Metadata;
metadata.CreateUI();
UIBase widget = (UIBase)metadata.View;
widget.BindUIHolder(holder, this);
ProcessWidget(metadata, true).Forget();
return (T)widget;
}
#endregion
#endregion
private async UniTask ProcessWidget(UIMetadata meta, bool visible) private async UniTask ProcessWidget(UIMetadata meta, bool visible)
{ {
AddWidget(meta); if (!AddWidget(meta)) return;
await meta.View.InternalInitlized(); await meta.View.InternalInitlized();
meta.View.Visible = visible; meta.View.Visible = visible;
if (meta.View.Visible) if (meta.View.Visible)
@ -103,13 +148,16 @@ namespace AlicizaX.UI.Runtime
} }
} }
private void AddWidget(UIMetadata meta) private bool AddWidget(UIMetadata meta)
{ {
if (!_children.TryAdd(meta.View, meta)) if (!_children.TryAdd(meta.View, meta))
{ {
Log.Warning("Already has widget:{0}", meta.View); Log.Warning("Already has widget:{0}", meta.View);
meta.Dispose(); meta.Dispose();
return false;
} }
return true;
} }
public async UniTask RemoveWidget(UIBase widget) public async UniTask RemoveWidget(UIBase widget)

View File

@ -105,7 +105,7 @@ namespace AlicizaX.UI.Runtime
var metadata = UIMetadataFactory.GetMetadata(typeHandle); var metadata = UIMetadataFactory.GetMetadata(typeHandle);
var parent = _tabCache[typeHandle]; var parent = _tabCache[typeHandle];
var widget = await CreateWidget(metadata, parent, false); var widget = await CreateWidgetUIAsync(metadata, parent, false);
if (widget is not UIWidget tabWidget) return; if (widget is not UIWidget tabWidget) return;
_loadedTabs[typeHandle] = tabWidget; _loadedTabs[typeHandle] = tabWidget;

View File

@ -38,7 +38,7 @@ namespace AlicizaX.UI.Runtime
obj.name = "------UI Root------"; obj.name = "------UI Root------";
_instanceRoot = obj.transform; _instanceRoot = obj.transform;
Object.DontDestroyOnLoad(_instanceRoot); Object.DontDestroyOnLoad(_instanceRoot);
_uiModule.Initlize(_instanceRoot,_isOrthographic); _uiModule.Initialize(_instanceRoot,_isOrthographic);
} }
private void Start() private void Start()