MenuOptions.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. using UnityEngine;
  2. using UnityEngine.EventSystems;
  3. using UnityEngine.UI;
  4. using UnityEditor;
  5. namespace WXB
  6. {
  7. static class UIMenuOptions
  8. {
  9. private const string kUILayerName = "UI";
  10. private const string kStandardSpritePath = "UI/Skin/UISprite.psd";
  11. private const string kBackgroundSpritePath = "UI/Skin/Background.psd";
  12. private const string kInputFieldBackgroundPath = "UI/Skin/InputFieldBackground.psd";
  13. private const string kKnobPath = "UI/Skin/Knob.psd";
  14. private const string kCheckmarkPath = "UI/Skin/Checkmark.psd";
  15. private const string kDropdownArrowPath = "UI/Skin/DropdownArrow.psd";
  16. private const string kMaskPath = "UI/Skin/UIMask.psd";
  17. static private DefaultControls.Resources s_StandardResources;
  18. static private DefaultControls.Resources GetStandardResources()
  19. {
  20. if (s_StandardResources.standard == null)
  21. {
  22. s_StandardResources.standard = AssetDatabase.GetBuiltinExtraResource<Sprite>(kStandardSpritePath);
  23. s_StandardResources.background = AssetDatabase.GetBuiltinExtraResource<Sprite>(kBackgroundSpritePath);
  24. s_StandardResources.inputField = AssetDatabase.GetBuiltinExtraResource<Sprite>(kInputFieldBackgroundPath);
  25. s_StandardResources.knob = AssetDatabase.GetBuiltinExtraResource<Sprite>(kKnobPath);
  26. s_StandardResources.checkmark = AssetDatabase.GetBuiltinExtraResource<Sprite>(kCheckmarkPath);
  27. s_StandardResources.dropdown = AssetDatabase.GetBuiltinExtraResource<Sprite>(kDropdownArrowPath);
  28. s_StandardResources.mask = AssetDatabase.GetBuiltinExtraResource<Sprite>(kMaskPath);
  29. }
  30. return s_StandardResources;
  31. }
  32. [MenuItem("GameObject/UI/富文本", false)]
  33. static public void AddSymbolText(MenuCommand menuCommand)
  34. {
  35. GameObject go = DefaultControls.CreateText(GetStandardResources());
  36. Object.DestroyImmediate(go.GetComponent<Text>());
  37. SymbolText st = go.AddComponent<SymbolText>();
  38. st.raycastTarget = false;
  39. st.rectTransform.pivot = Vector2.zero;
  40. PlaceUIElementRoot(go, menuCommand);
  41. }
  42. private static void SetPositionVisibleinSceneView(RectTransform canvasRTransform, RectTransform itemTransform)
  43. {
  44. // Find the best scene view
  45. SceneView sceneView = SceneView.lastActiveSceneView;
  46. if (sceneView == null && SceneView.sceneViews.Count > 0)
  47. sceneView = SceneView.sceneViews[0] as SceneView;
  48. // Couldn't find a SceneView. Don't set position.
  49. if (sceneView == null || sceneView.camera == null)
  50. return;
  51. // Create world space Plane from canvas position.
  52. Vector2 localPlanePosition;
  53. Camera camera = sceneView.camera;
  54. Vector3 position = Vector3.zero;
  55. if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRTransform, new Vector2(camera.pixelWidth / 2, camera.pixelHeight / 2), camera, out localPlanePosition))
  56. {
  57. // Adjust for canvas pivot
  58. localPlanePosition.x = localPlanePosition.x + canvasRTransform.sizeDelta.x * canvasRTransform.pivot.x;
  59. localPlanePosition.y = localPlanePosition.y + canvasRTransform.sizeDelta.y * canvasRTransform.pivot.y;
  60. localPlanePosition.x = Mathf.Clamp(localPlanePosition.x, 0, canvasRTransform.sizeDelta.x);
  61. localPlanePosition.y = Mathf.Clamp(localPlanePosition.y, 0, canvasRTransform.sizeDelta.y);
  62. // Adjust for anchoring
  63. position.x = localPlanePosition.x - canvasRTransform.sizeDelta.x * itemTransform.anchorMin.x;
  64. position.y = localPlanePosition.y - canvasRTransform.sizeDelta.y * itemTransform.anchorMin.y;
  65. Vector3 minLocalPosition;
  66. minLocalPosition.x = canvasRTransform.sizeDelta.x * (0 - canvasRTransform.pivot.x) + itemTransform.sizeDelta.x * itemTransform.pivot.x;
  67. minLocalPosition.y = canvasRTransform.sizeDelta.y * (0 - canvasRTransform.pivot.y) + itemTransform.sizeDelta.y * itemTransform.pivot.y;
  68. Vector3 maxLocalPosition;
  69. maxLocalPosition.x = canvasRTransform.sizeDelta.x * (1 - canvasRTransform.pivot.x) - itemTransform.sizeDelta.x * itemTransform.pivot.x;
  70. maxLocalPosition.y = canvasRTransform.sizeDelta.y * (1 - canvasRTransform.pivot.y) - itemTransform.sizeDelta.y * itemTransform.pivot.y;
  71. position.x = Mathf.Clamp(position.x, minLocalPosition.x, maxLocalPosition.x);
  72. position.y = Mathf.Clamp(position.y, minLocalPosition.y, maxLocalPosition.y);
  73. }
  74. itemTransform.anchoredPosition = position;
  75. itemTransform.localRotation = Quaternion.identity;
  76. itemTransform.localScale = Vector3.one;
  77. }
  78. private static void PlaceUIElementRoot(GameObject element, MenuCommand menuCommand)
  79. {
  80. GameObject parent = menuCommand.context as GameObject;
  81. if (parent == null || parent.GetComponentInParent<Canvas>() == null)
  82. {
  83. parent = GetOrCreateCanvasGameObject();
  84. }
  85. string uniqueName = GameObjectUtility.GetUniqueNameForSibling(parent.transform, element.name);
  86. element.name = uniqueName;
  87. Undo.RegisterCreatedObjectUndo(element, "Create " + element.name);
  88. Undo.SetTransformParent(element.transform, parent.transform, "Parent " + element.name);
  89. GameObjectUtility.SetParentAndAlign(element, parent);
  90. if (parent != menuCommand.context) // not a context click, so center in sceneview
  91. SetPositionVisibleinSceneView(parent.GetComponent<RectTransform>(), element.GetComponent<RectTransform>());
  92. Selection.activeGameObject = element;
  93. }
  94. static void CheckRaycastTarget(GameObject go)
  95. {
  96. Graphic g = go.GetComponent<Graphic>();
  97. if (g != null)
  98. g.raycastTarget = true;
  99. }
  100. // Helper methods
  101. static public GameObject CreateNewUI()
  102. {
  103. // Root for the UI
  104. var root = new GameObject("Canvas");
  105. root.layer = LayerMask.NameToLayer(kUILayerName);
  106. Canvas canvas = root.AddComponent<Canvas>();
  107. canvas.renderMode = RenderMode.ScreenSpaceOverlay;
  108. root.AddComponent<CanvasScaler>();
  109. root.AddComponent<GraphicRaycaster>();
  110. Undo.RegisterCreatedObjectUndo(root, "Create " + root.name);
  111. // if there is no event system add one...
  112. CreateEventSystem(false);
  113. return root;
  114. }
  115. private static void CreateEventSystem(bool select)
  116. {
  117. CreateEventSystem(select, null);
  118. }
  119. private static void CreateEventSystem(bool select, GameObject parent)
  120. {
  121. var esys = Object.FindObjectOfType<EventSystem>();
  122. if (esys == null)
  123. {
  124. var eventSystem = new GameObject("EventSystem");
  125. GameObjectUtility.SetParentAndAlign(eventSystem, parent);
  126. esys = eventSystem.AddComponent<EventSystem>();
  127. eventSystem.AddComponent<StandaloneInputModule>();
  128. Undo.RegisterCreatedObjectUndo(eventSystem, "Create " + eventSystem.name);
  129. }
  130. if (select && esys != null)
  131. {
  132. Selection.activeGameObject = esys.gameObject;
  133. }
  134. }
  135. // Helper function that returns a Canvas GameObject; preferably a parent of the selection, or other existing Canvas.
  136. static public GameObject GetOrCreateCanvasGameObject()
  137. {
  138. GameObject selectedGo = Selection.activeGameObject;
  139. // Try to find a gameobject that is the selected GO or one if its parents.
  140. Canvas canvas = (selectedGo != null) ? selectedGo.GetComponentInParent<Canvas>() : null;
  141. if (canvas != null && canvas.gameObject.activeInHierarchy)
  142. return canvas.gameObject;
  143. // No canvas in selection or its parents? Then use just any canvas..
  144. canvas = Object.FindObjectOfType(typeof(Canvas)) as Canvas;
  145. if (canvas != null && canvas.gameObject.activeInHierarchy)
  146. return canvas.gameObject;
  147. // No canvas in the scene at all? Then create a new one.
  148. return UIMenuOptions.CreateNewUI();
  149. }
  150. }
  151. }