using System.Collections; using System.Collections.Generic; using AppUI.Manager; using UnityEngine; using UnityEngine.UI; namespace AppUI.Manager.View { public enum UIPrefabsFolder { Home, Component, Infrared, Manager, Module, User, Util } public enum UIViewType { HomeView, UserCenterView, DeviceView, DeviceArcheryView, DeviceGunView, PositioningView, InfraredView, SettingsView, SocialView, PersonalView, ConnectGuidanceView, InfraredScreenPositioningView, CalibrationView, HomeViewTip, GameResultView, /**旧页面或者未完成的页面**/ RankingView, GyrGuidanceView, MagGuidanceView, ModeSelectView, RoleSelectView, PKMatchView, RelateValidateView, RetrievePasswordView, } public enum UIPrefabType { AuthLoginMask, SmartBowDeviceHub, ModuleView, ModuleGuestView, ModuleViewHorizontal, ModuleSideSlip, RetrievePasswordView } public class ViewConfig { public string path; public int groupIndex; public bool overrideSorting; } public class ViewManager { private static readonly string currentPrefix = "Wonderfitter/"; private static GameObject currentViewParent; static Transform GetViewParent(int groupIndex) => ViewMgr.EnsureGroup(groupIndex); private class ViewCacheInfo { public string fullPath; public GameObject gameObject; } private static readonly List _ViewCacheInfos = new(); // ========================= // 🔥 配置中心(替代所有 if) // ========================= private static readonly Dictionary ViewConfigs = new() { { UIViewType.HomeView, new ViewConfig { path = "Home/HomeView", } },{ UIViewType.UserCenterView, new ViewConfig { path = "Home/UserCenterView", } },{ UIViewType.DeviceView, new ViewConfig { path = "Home/DeviceView", groupIndex = 0, } },{ UIViewType.PositioningView, new ViewConfig { path = "Infrared/PositioningView", groupIndex = 0, } },{ UIViewType.InfraredView, new ViewConfig { path = "Infrared/InfraredView", groupIndex = 0, } },{ UIViewType.SettingsView, new ViewConfig { path = "Home/SettingsView", groupIndex = 0, } },{ UIViewType.RankingView, new ViewConfig { path = "Home/RankingView", groupIndex = 0, } }, { UIViewType.DeviceArcheryView, new ViewConfig { path = "Home/DeviceArcheryView" } }, { UIViewType.DeviceGunView, new ViewConfig { path = "Home/DeviceGunView" } }, { UIViewType.GyrGuidanceView, new ViewConfig { path = "NineAxis/GyrGuidanceView" } }, { UIViewType.MagGuidanceView, new ViewConfig { path = "NineAxis/MagGuidanceView" } },{ UIViewType.ModeSelectView, new ViewConfig { path = "Home/ModeSelectView" } }, { UIViewType.GameResultView, new ViewConfig { path = "Common/GameResultView", groupIndex = 0, overrideSorting = true } }, { UIViewType.RoleSelectView, new ViewConfig { path = "Home/RoleSelectView", groupIndex = 0, overrideSorting = true } }, { UIViewType.PKMatchView, new ViewConfig { path = "Home/PKMatchView", groupIndex = 0, overrideSorting = true } }, { UIViewType.InfraredScreenPositioningView, new ViewConfig { path = "Infrared/InfraredScreenPositioningView", groupIndex = 1, overrideSorting = false } }, { UIViewType.CalibrationView, new ViewConfig { path = "Infrared/CalibrationView", groupIndex = 1, overrideSorting = false } }, { UIViewType.RelateValidateView, new ViewConfig { path = "RelateValidateView/RelateValidateView", } }, { UIViewType.RetrievePasswordView, new ViewConfig { path = "User/RetrievePasswordView", } } }; /** * 定义一些常用的预制体路径配置,如 ModuleView,避免在代码中硬编码字符串路径,同时也方便后续维护和修改。 */ private static readonly Dictionary UIPrefabConfigs = new() { { UIPrefabType.AuthLoginMask,//用户登陆的mask(BowArrow/Resources 下) new ViewConfig { path = "Textures/GameIcon/Prefabs/Parts/Home/AuthLoginMask/AuthLoginMask" } }, { UIPrefabType.SmartBowDeviceHub, new ViewConfig { path = currentPrefix + "Bluetooth/SmartBowDeviceHub" } }, { UIPrefabType.ModuleView, new ViewConfig { path = currentPrefix + "Module/ModuleView" } },{ UIPrefabType.ModuleGuestView, new ViewConfig { path = currentPrefix + "Module/ModuleGuestView" } }, { UIPrefabType.ModuleViewHorizontal, new ViewConfig { path = currentPrefix + "Module/ModuleViewHorizontal" } }, { UIPrefabType.ModuleSideSlip, new ViewConfig { path = currentPrefix + "Module/ModuleSideSlip" } } , { UIPrefabType.RetrievePasswordView, new ViewConfig { path = currentPrefix + "User/RetrievePasswordView", } } }; // ========================= // Show // ========================= public static GameObject ShowView(UIViewType type) { ViewConfig config = ViewConfigs[type]; return InstantiateView(config.path, type); } // ========================= // Hide // ========================= public static void HideView(UIViewType type) { _DestroyExistViews(GetFullPath(type)); } public static void HideView(UIPrefabsFolder folder = UIPrefabsFolder.Home) { _DestroyExistViews(ResolveFullPath(folder)); } public static void RemoveView(GameObject view) { if (!view) return; _ViewCacheInfos.RemoveAll(e => { if (e.gameObject == view) { Object.Destroy(e.gameObject); return true; } return false; }); } private static string GetFullPath(UIViewType type) { if (ViewConfigs.TryGetValue(type, out ViewConfig config)) return currentPrefix + config.path; return currentPrefix + GetConfig(type).path; } static string ResolveFullPath(UIPrefabsFolder folder) { string typeName = typeof(T).Name; if (System.Enum.TryParse(typeName, out UIViewType viewType)) return GetFullPath(viewType); return currentPrefix + $"{folder}/{typeName}"; } public static void RemoveView(UIPrefabsFolder folder = UIPrefabsFolder.Home) { _RemoveView(ResolveFullPath(folder)); } // ========================= // Instantiate Core // ========================= private static GameObject InstantiateView(string path, UIViewType type) { _ = ViewMgr.Instance; ViewConfig config = GetConfig(type); currentViewParent = GetViewParent(config.groupIndex).gameObject; string fullPath = currentPrefix + path; _DestroyExistViews(fullPath); GameObject prefab = Resources.Load(fullPath); if (prefab == null) { Debug.LogError($"ViewManager: Resources 中未找到预制体 \"{fullPath}\""); return null; } GameObject o = Object.Instantiate(prefab, currentViewParent.transform); // ========================= // sorting(无 if 判断) // ========================= if (config.overrideSorting) { Canvas canvas = o.GetComponent(); if (canvas != null) canvas.overrideSorting = true; } // ========================= // UI适配 // ========================= RectTransform rectTransform = RemoveCanvasScaler(o.transform); if (rectTransform != null) { if (rectTransform == o.GetComponent()) { rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; rectTransform.localScale = Vector3.one; } else { rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.localScale = Vector3.one; rectTransform.sizeDelta = ((RectTransform)currentViewParent.transform).rect.size; rectTransform.anchoredPosition = Vector2.zero; } } _ViewCacheInfos.Add(new ViewCacheInfo { fullPath = fullPath, gameObject = o }); return o; } // ========================= // Config getter // ========================= private static ViewConfig GetConfig(UIViewType type) { if (ViewConfigs.TryGetValue(type, out var config)) return config; return new ViewConfig { path = type.ToString(), groupIndex = 0, overrideSorting = false }; } public static ViewConfig GetConfig(UIPrefabType type) { if (UIPrefabConfigs.TryGetValue(type, out var config)) return config; return new ViewConfig { path = type.ToString(), groupIndex = 0, overrideSorting = false }; } public static GameObject GetPrefabByType(UIPrefabType type) { string path = GetConfig(type).path; GameObject prefab = Resources.Load(path); if (prefab == null) Debug.LogError($"ViewManager: Resources 中未找到预制体 \"{path}\" (UIPrefabType.{type})"); return prefab; } // ========================= // Remove CanvasScaler // ========================= private static RectTransform RemoveCanvasScaler(Transform parent) { Canvas canvas = parent.GetComponent(); if (canvas != null) { CanvasScaler scaler = parent.GetComponent(); if (scaler != null) { Object.Destroy(scaler); return parent.GetComponent(); } } foreach (Transform child in parent) { RectTransform result = RemoveCanvasScaler(child); if (result != null) return result; } return null; } // ========================= // Hide All // ========================= public static void HideAllView() { foreach (var v in _ViewCacheInfos) { if (v.gameObject) Object.Destroy(v.gameObject); } _ViewCacheInfos.Clear(); } // ========================= // Destroy logic // ========================= private static void _DestroyExistViews(string fullPath) { _ViewCacheInfos.FindAll(e => e.fullPath == fullPath).ForEach(e => { if (e.gameObject) Object.Destroy(e.gameObject); }); _ViewCacheInfos.RemoveAll(e => e.fullPath == fullPath); } private static void _RemoveView(string fullPath) { _ViewCacheInfos.RemoveAll(e => e.fullPath == fullPath); } } }