Unity 框架

AxisTool.cs 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEditor;
  4. using UnityEditor.EditorTools;
  5. namespace TFramework
  6. {
  7. [EditorTool("AxisTool", typeof(Transform))]
  8. public class AxisTool : EditorTool
  9. {
  10. private GUIContent uIContent;
  11. private Transform _target;
  12. private List<Transform> chlids = new List<Transform>();
  13. private Axis axis = Axis.X;
  14. private GUIContent centerConter;
  15. public GUIContent CenterConter
  16. {
  17. get
  18. {
  19. if (centerConter == null)
  20. {
  21. centerConter = new GUIContent();
  22. centerConter.image = EditorGUIUtility.IconContent("Grid.MoveTool").image;
  23. centerConter.tooltip = "居中所有轴";
  24. }
  25. return centerConter;
  26. }
  27. }
  28. public override GUIContent toolbarIcon
  29. {
  30. get
  31. {
  32. if (uIContent == null)
  33. {
  34. uIContent = new GUIContent();
  35. uIContent.tooltip = "AxisTool";
  36. uIContent.image = EditorGUIUtility.IconContent("AvatarPivot").image;
  37. }
  38. return uIContent;
  39. }
  40. }
  41. private void OnEnable()
  42. {
  43. ToolManager.activeToolChanged += TargetChangeEvent;
  44. Selection.selectionChanged += TargetChangeEvent;
  45. }
  46. private void TargetChangeEvent()
  47. {
  48. if (!ToolManager.IsActiveTool(this))
  49. return;
  50. _target = target as Transform;
  51. chlids.Clear();
  52. foreach (Transform item in _target)
  53. {
  54. chlids.Add(item);
  55. }
  56. }
  57. private void OnDisable()
  58. {
  59. ToolManager.activeToolChanged -= TargetChangeEvent;
  60. Selection.selectionChanged -= TargetChangeEvent;
  61. }
  62. public override void OnToolGUI(EditorWindow window)
  63. {
  64. if (_target == null) return;
  65. Rect rect = new Rect(window.position.width - 200, window.position.height - 170, 160, 50);
  66. int id = GUIUtility.GetControlID(FocusType.Passive, rect);
  67. HandleUtility.AddDefaultControl(id);
  68. using (new Handles.DrawingScope())
  69. {
  70. EditorGUI.BeginChangeCheck();
  71. Vector3 newPos = Handles.PositionHandle(_target.position, Quaternion.identity);
  72. if (EditorGUI.EndChangeCheck())
  73. {
  74. Undo.RecordObject(_target, "Move Pivot");
  75. Vector3 dir = newPos - _target.position;
  76. _target.position = newPos;
  77. for (int i = 0; i < chlids.Count; i++)
  78. {
  79. Undo.RecordObject(chlids[i], "Move Pivot");
  80. chlids[i].position -= dir;
  81. }
  82. EditorUtility.SetDirty(_target);
  83. AssetDatabase.SaveAssets();
  84. }
  85. }
  86. Handles.BeginGUI();
  87. GUI.Box(rect, "", "Window");
  88. rect.Set(rect.x + 3, rect.y + 3, 20, 20);
  89. GUI.Label(rect, "轴");
  90. rect.Set(rect.x + 20, rect.y + 1, 80, 20);
  91. axis = (Axis)EditorGUI.EnumPopup(rect, axis);
  92. rect.Set(rect.x + 80, rect.y - 1, 20, 20);
  93. if (GUI.Button(rect, CenterConter))
  94. {
  95. SetAxis(2);
  96. }
  97. rect.Set(rect.x - 100, rect.y + 23, 50, 20);
  98. if (GUI.Button(rect, axis == Axis.Y ? "上" : (axis == Axis.X ? "左" : "前")))
  99. {
  100. SetAxis(-1);
  101. }
  102. rect.Set(rect.x + 50, rect.y, 50, 20);
  103. if (GUI.Button(rect, "中"))
  104. {
  105. SetAxis(0);
  106. }
  107. rect.Set(rect.x + 50, rect.y, 50, 20);
  108. if (GUI.Button(rect, axis == Axis.Y ? "下" : (axis == Axis.X ? "右" : "后")))
  109. {
  110. SetAxis(1);
  111. }
  112. GUI.enabled = true;
  113. Handles.EndGUI();
  114. }
  115. void SetAxis(int pos)
  116. {
  117. Bounds bounds = GetBounds(_target);
  118. if (pos == 2)
  119. {
  120. _target.position += bounds.center;
  121. foreach (Transform item in _target)
  122. {
  123. item.position -= bounds.center;
  124. }
  125. return;
  126. }
  127. float value = 0;
  128. switch (axis)
  129. {
  130. case Axis.X:
  131. value = pos == -1 ? bounds.center.x + bounds.size.x / 2 : (pos == 0 ? bounds.center.x : bounds.center.x - bounds.size.x / 2);
  132. _target.position = new Vector3(_target.position.x + value, _target.position.y, _target.position.z);
  133. foreach (Transform item in _target)
  134. {
  135. item.position = new Vector3(item.position.x - value, item.position.y, item.position.z);
  136. }
  137. break;
  138. case Axis.Y:
  139. value = pos == -1 ? bounds.center.y + bounds.size.y / 2 : (pos == 0 ? bounds.center.y : bounds.center.y - bounds.size.y / 2);
  140. _target.position = new Vector3(_target.position.x, _target.position.y + value, _target.position.z);
  141. foreach (Transform item in _target)
  142. {
  143. item.position = new Vector3(item.position.x, item.position.y - value, item.position.z);
  144. }
  145. break;
  146. case Axis.Z:
  147. value = pos == -1 ? bounds.center.z + bounds.size.z / 2 : (pos == 0 ? bounds.center.z : bounds.center.z - bounds.size.z / 2);
  148. _target.position = new Vector3(_target.position.x, _target.position.y, _target.position.z + value);
  149. foreach (Transform item in _target)
  150. {
  151. item.position = new Vector3(item.position.x, item.position.y, item.position.z - value);
  152. }
  153. break;
  154. }
  155. EditorUtility.SetDirty(_target);
  156. AssetDatabase.SaveAssets();
  157. }
  158. Bounds GetBounds(Transform target)
  159. {
  160. Renderer[] renders = target.GetComponentsInChildren<Renderer>();
  161. Bounds bounds = new Bounds(Vector3.zero, Vector3.zero);
  162. if (renders.Length == 0) return bounds;
  163. Vector3 postion = target.position;
  164. Quaternion rotation = target.rotation;
  165. Vector3 scale = target.localScale;
  166. target.position = Vector3.zero;
  167. target.localScale = Vector3.one;
  168. Vector3 center = Vector3.zero;
  169. foreach (Renderer child in renders)
  170. {
  171. center += child.bounds.center;
  172. }
  173. center /= renders.Length;
  174. bounds.center = center;
  175. foreach (Renderer child in renders)
  176. {
  177. bounds.Encapsulate(child.bounds);
  178. }
  179. target.position = postion;
  180. target.localScale = scale;
  181. return bounds;
  182. }
  183. enum Axis
  184. {
  185. X,
  186. Y,
  187. Z
  188. }
  189. }
  190. }