using System.Collections.Generic; using Cysharp.Threading.Tasks; using FairyGUI; using YooAsset; namespace Script.FrameWork.UI { public class UIManager : Singleton { private Dictionary _uiPages = new(); // 资源句柄列表 private Dictionary _handles = new(); // 常驻资源白名单 private List _permanentPackages = new(); private object LoadFunc(string name, string extension, System.Type type, out DestroyMethod method) { method = DestroyMethod.None; //注意:这里一定要设置为None var package = YooAssets.GetPackage("DefaultPackage"); var handle = package.LoadAssetSync(name , type); if (!_handles.ContainsKey(name)) _handles.Add(name, handle); return handle.AssetObject; } public override void Init() { // UIPackage.AddPackage("Common", LoadFunc); // UIPackage.AddPackage("Sound", LoadFunc); // UIPackage.AddPackage("PageLoading", LoadFunc); // UIConfig.buttonSound = (NAudioClip)UIPackage.GetItemAssetByURL("ui://Sound/Click"); // GRoot.inst.EnableSound(); } public override void UnInit() { } public bool IsActive() { var pageName = typeof(T).Name; if (_uiPages.TryGetValue(pageName, out var page)) return page.IsLoaded; return false; } public async UniTask ShowUI(string resPath = "", UIParam param = null) where T : UIPage, new() { string pkgName; string resName; if (!string.IsNullOrEmpty(resPath)) { if (!GetUIPkgAndResName(resPath, out pkgName, out resName)) return; } else { pkgName = typeof(T).Name; resName = typeof(T).Name; } UIPackage.AddPackage(pkgName, LoadFunc); if (!_uiPages.TryGetValue(resName, out var uiPage)) { uiPage = new T(); _uiPages.Add(resName, uiPage); } if (uiPage.IsLoaded) { uiPage.Show(); } else { if (uiPage.IsLoading) { // 正在加载中 } else { UIPackage.CreateObjectAsync(pkgName, resName, obj => { float width = GRoot.inst.width; float height = GRoot.inst.height; var panel = obj as GComponent; var window = new Window { contentPane = panel }; // window.x = width / 2 - window.width / 2; // window.y = height / 2 - window.height / 2; panel.SetSize(width, height); uiPage.Create(window, panel); uiPage.Init(param); uiPage.InitEvents(); uiPage.Show(); }); uiPage.IsLoading = true; await UniTask.WaitUntil(() => uiPage.IsLoaded); } } } public async UniTask CloseUI() { var pageName = typeof(T).Name; // packageName和pageName一致 var packageName = pageName; if (_uiPages.TryGetValue(pageName, out var page)) { if (page.IsLoaded) { await page.Close(); } _uiPages.Remove(pageName); if (!_permanentPackages.Contains(packageName)) { if (_handles.TryGetValue(packageName, out var handle)) { handle.Release(); _handles.Remove(packageName); } } UIPackage.RemovePackage(packageName); } } public void Update(float deltaTime) { foreach (var (uiName, page) in _uiPages) { if (page.IsLoading || !page.IsLoaded) continue; page.Update(deltaTime); } } private bool GetUIPkgAndResName(string resPath, out string pkgName, out string resName) { pkgName = ""; resName = ""; var arr = resPath.Split('/'); if (arr.Length < 2) { LogHelper.LogError($"UI ResPath Error: {resPath}"); return false; } pkgName = arr[0]; resName = arr[1]; return true; } } }