ViewMgr.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using AppUI.Manager.View;
  2. using UnityEngine;
  3. using UnityEngine.SceneManagement;
  4. using UnityEngine.UI;
  5. namespace AppUI.Manager
  6. {
  7. /// <summary>
  8. /// AppUI UI 根节点:创建 Canvas、默认分组 "0",以及按需克隆出的上层分组(如 "1")。
  9. /// 预制体与页面逻辑见 <see cref="View.ViewManager"/>。
  10. /// </summary>
  11. public class ViewMgr : MonoBehaviour
  12. {
  13. const string DefaultGroupName = "0";
  14. static ViewMgr s_Instance;
  15. static bool s_SceneHookRegistered;
  16. public static ViewMgr Instance
  17. {
  18. get
  19. {
  20. if (s_Instance == null)
  21. {
  22. var go = new GameObject(nameof(ViewMgr));
  23. s_Instance = go.AddComponent<ViewMgr>();
  24. DontDestroyOnLoad(go);
  25. s_Instance.SetupRoot();
  26. }
  27. return s_Instance;
  28. }
  29. }
  30. public static bool HasInstance() => s_Instance != null;
  31. /// <summary>
  32. /// 初始化 UI 根节点,并确保红外等上层分组 "1" 已创建(仅需在 Home 场景入口调用一次)。
  33. /// </summary>
  34. public static void EnsureInitialized()
  35. {
  36. _ = Instance;
  37. EnsureGroup(1);
  38. }
  39. /// <summary>
  40. /// 获取或创建指定分组节点;groupIndex 为 0 时返回默认全屏分组。
  41. /// </summary>
  42. public static Transform EnsureGroup(int groupIndex)
  43. {
  44. _ = Instance;
  45. string groupName = groupIndex.ToString();
  46. Transform existing = Instance.transform.Find(groupName);
  47. if (existing)
  48. return existing;
  49. if (groupIndex == 0)
  50. {
  51. Instance.CreateDefaultGroup();
  52. return Instance.transform.Find(DefaultGroupName);
  53. }
  54. Transform template = Instance.transform.Find(DefaultGroupName);
  55. if (!template)
  56. {
  57. Instance.CreateDefaultGroup();
  58. template = Instance.transform.Find(DefaultGroupName);
  59. }
  60. return Instance.CreateGroupFromTemplate(template, groupIndex);
  61. }
  62. void OnDestroy()
  63. {
  64. if (s_SceneHookRegistered)
  65. {
  66. SceneManager.sceneUnloaded -= OnSceneUnloaded;
  67. s_SceneHookRegistered = false;
  68. }
  69. if (s_Instance == this)
  70. s_Instance = null;
  71. }
  72. static void EnsureSceneHook()
  73. {
  74. if (s_SceneHookRegistered)
  75. return;
  76. s_SceneHookRegistered = true;
  77. SceneManager.sceneUnloaded += OnSceneUnloaded;
  78. }
  79. static void OnSceneUnloaded(Scene scene)
  80. {
  81. ViewManager.HideAllView();
  82. if (scene.name == "InfraredGameDouble" || scene.name == "WildAttackDouble")
  83. {
  84. InfraredDemo._ins?.SetSinglePoint(true);
  85. Debug.Log("OnSceneUnloaded 取消设置单点模式");
  86. }
  87. }
  88. void SetupRoot()
  89. {
  90. gameObject.layer = LayerMask.NameToLayer("UI");
  91. Canvas viewCanvas = gameObject.AddComponent<Canvas>();
  92. viewCanvas.renderMode = RenderMode.ScreenSpaceOverlay;
  93. viewCanvas.sortingOrder = 1;
  94. CanvasScaler viewMgrCanvasScaler = gameObject.AddComponent<CanvasScaler>();
  95. viewMgrCanvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
  96. viewMgrCanvasScaler.referenceResolution = new Vector2(2532, 1170);
  97. viewMgrCanvasScaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
  98. viewMgrCanvasScaler.matchWidthOrHeight = 0f;
  99. gameObject.AddComponent<GraphicRaycaster>();
  100. CreateDefaultGroup();
  101. EnsureSceneHook();
  102. }
  103. void CreateDefaultGroup()
  104. {
  105. if (transform.Find(DefaultGroupName))
  106. return;
  107. var rectTransform = new GameObject(DefaultGroupName).AddComponent<RectTransform>();
  108. rectTransform.gameObject.layer = LayerMask.NameToLayer("UI");
  109. rectTransform.SetParent(transform);
  110. rectTransform.localPosition = Vector3.zero;
  111. rectTransform.localScale = Vector3.one;
  112. rectTransform.anchorMin = Vector2.zero;
  113. rectTransform.anchorMax = Vector2.one;
  114. rectTransform.offsetMin = Vector2.zero;
  115. rectTransform.offsetMax = Vector2.zero;
  116. }
  117. Transform CreateGroupFromTemplate(Transform template, int groupIndex)
  118. {
  119. string groupName = groupIndex.ToString();
  120. var newObj = new GameObject(groupName);
  121. newObj.layer = LayerMask.NameToLayer("UI");
  122. newObj.transform.SetParent(transform);
  123. newObj.transform.localPosition = template.localPosition;
  124. newObj.transform.localRotation = template.localRotation;
  125. newObj.transform.localScale = template.localScale;
  126. RectTransform rectTransform = newObj.AddComponent<RectTransform>();
  127. if (template is RectTransform templateRect)
  128. {
  129. rectTransform.anchorMin = templateRect.anchorMin;
  130. rectTransform.anchorMax = templateRect.anchorMax;
  131. rectTransform.offsetMin = templateRect.offsetMin;
  132. rectTransform.offsetMax = templateRect.offsetMax;
  133. }
  134. for (int i = 0; i < transform.childCount - 1; i++)
  135. {
  136. if (!int.TryParse(transform.GetChild(i).gameObject.name, out int siblingIndex))
  137. continue;
  138. if (groupIndex < siblingIndex)
  139. {
  140. rectTransform.SetSiblingIndex(i);
  141. break;
  142. }
  143. }
  144. return rectTransform;
  145. }
  146. }
  147. }