暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ScriptablePathInspector.cs 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEditor;
  6. namespace UnityEditor.U2D.Path
  7. {
  8. [CanEditMultipleObjects]
  9. [CustomEditor(typeof(ScriptablePath), true)]
  10. public class ScriptablePathInspector : Editor
  11. {
  12. private static class Contents
  13. {
  14. public static readonly GUIContent linearIcon = IconContent("TangentLinear", "TangentLinearPro", "Linear");
  15. public static readonly GUIContent continuousIcon = IconContent("TangentContinuous", "TangentContinuousPro", "Continuous");
  16. public static readonly GUIContent brokenIcon = IconContent("TangentBroken", "TangentBrokenPro", "Broken");
  17. public static readonly GUIContent positionLabel = new GUIContent("Position", "Position of the Control Point");
  18. public static readonly GUIContent enableSnapLabel = new GUIContent("Snapping", "Snap points using the snap settings");
  19. public static readonly GUIContent tangentModeLabel = new GUIContent("Tangent Mode");
  20. public static readonly GUIContent pointLabel = new GUIContent("Point");
  21. private static GUIContent IconContent(string name, string tooltip = null)
  22. {
  23. return new GUIContent(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/" + name + ".png"), tooltip);
  24. }
  25. private static GUIContent IconContent(string personal, string pro, string tooltip)
  26. {
  27. if (EditorGUIUtility.isProSkin)
  28. return IconContent(pro, tooltip);
  29. return IconContent(personal, tooltip);
  30. }
  31. }
  32. private List<ScriptablePath> m_Paths = null;
  33. private bool m_Dragged = false;
  34. protected List<ScriptablePath> paths
  35. {
  36. get
  37. {
  38. if (m_Paths == null)
  39. m_Paths = targets.Select( t => t as ScriptablePath).ToList();
  40. return m_Paths;
  41. }
  42. }
  43. public override void OnInspectorGUI()
  44. {
  45. DoTangentModeInspector();
  46. DoPositionInspector();
  47. }
  48. protected void DoTangentModeInspector()
  49. {
  50. if (!IsAnyShapeType(ShapeType.Spline))
  51. return;
  52. EditorGUILayout.BeginHorizontal();
  53. EditorGUILayout.PrefixLabel(Contents.tangentModeLabel);
  54. using (new EditorGUI.DisabledGroupScope(!IsAnyPointSelected()))
  55. {
  56. if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Linear), Contents.linearIcon))
  57. SetMixedTangentMode(TangentMode.Linear);
  58. if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Continuous), Contents.continuousIcon))
  59. SetMixedTangentMode(TangentMode.Continuous);
  60. if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Broken), Contents.brokenIcon))
  61. SetMixedTangentMode(TangentMode.Broken);
  62. }
  63. EditorGUILayout.EndHorizontal();
  64. }
  65. protected void DoPositionInspector()
  66. {
  67. var showMixedValue = EditorGUI.showMixedValue;
  68. var wideMode = EditorGUIUtility.wideMode;
  69. var position = Vector3.zero;
  70. var isMixed = GetMixedPosition(out position);
  71. EditorGUI.showMixedValue = isMixed;
  72. EditorGUIUtility.wideMode = true;
  73. using (new EditorGUI.DisabledGroupScope(!IsAnyPointSelected()))
  74. {
  75. if (GUIUtility.hotControl == 0)
  76. m_Dragged = false;
  77. EditorGUI.BeginChangeCheck();
  78. var delta = EditorGUILayout.Vector2Field(Contents.positionLabel, position) - (Vector2)position;
  79. if (EditorGUI.EndChangeCheck())
  80. {
  81. if (m_Dragged == false)
  82. {
  83. foreach(var path in paths)
  84. path.undoObject.RegisterUndo("Point Position");
  85. m_Dragged = true;
  86. }
  87. SetMixedDeltaPosition(delta);
  88. }
  89. }
  90. EditorGUI.showMixedValue = showMixedValue;
  91. EditorGUIUtility.wideMode = wideMode;
  92. }
  93. private bool DoToggle(bool value, GUIContent icon)
  94. {
  95. const float kButtonWidth = 33f;
  96. const float kButtonHeight = 23f;
  97. var buttonStyle = new GUIStyle("EditModeSingleButton");
  98. var changed = false;
  99. using (var check = new EditorGUI.ChangeCheckScope())
  100. {
  101. value = GUILayout.Toggle(value, icon, buttonStyle, GUILayout.Width(kButtonWidth), GUILayout.Height(kButtonHeight));
  102. changed = check.changed;
  103. }
  104. return value && changed;
  105. }
  106. private bool GetToggleStateFromTangentMode(TangentMode mode)
  107. {
  108. foreach(var path in paths)
  109. {
  110. var selection = path.selection;
  111. foreach (var index in selection.elements)
  112. if (path.GetPoint(index).tangentMode != mode)
  113. return false;
  114. }
  115. return true;
  116. }
  117. private void SetMixedTangentMode(TangentMode tangentMode)
  118. {
  119. foreach(var path in paths)
  120. {
  121. path.undoObject.RegisterUndo("Tangent Mode");
  122. foreach (var index in path.selection.elements)
  123. path.SetTangentMode(index, tangentMode);
  124. }
  125. SceneView.RepaintAll();
  126. }
  127. private bool GetMixedPosition(out Vector3 position)
  128. {
  129. var first = true;
  130. position = Vector3.zero;
  131. var activeObject = Selection.activeObject as GameObject;
  132. if (Selection.count > 1 || !activeObject)
  133. return true;
  134. foreach(var path in paths)
  135. {
  136. MonoBehaviour behavior = path.owner as MonoBehaviour;
  137. if (!behavior || activeObject != behavior.gameObject)
  138. continue;
  139. var selection = path.selection;
  140. foreach (var index in selection.elements)
  141. {
  142. var controlPoint = path.GetPointLocal(index);
  143. if (first)
  144. {
  145. position = controlPoint.position;
  146. first = false;
  147. }
  148. else if (position != controlPoint.position)
  149. {
  150. return true;
  151. }
  152. }
  153. }
  154. return false;
  155. }
  156. private void SetMixedDeltaPosition(Vector3 delta)
  157. {
  158. foreach(var path in paths)
  159. {
  160. var selection = path.selection;
  161. var matrix = path.localToWorldMatrix;
  162. path.localToWorldMatrix = Matrix4x4.identity;
  163. foreach (var index in selection.elements)
  164. {
  165. var controlPoint = path.GetPoint(index);
  166. controlPoint.position += delta;
  167. path.SetPoint(index, controlPoint);
  168. }
  169. path.localToWorldMatrix = matrix;
  170. }
  171. }
  172. private bool IsAnyShapeType(ShapeType shapeType)
  173. {
  174. foreach(var path in paths)
  175. if (path.shapeType == shapeType)
  176. return true;
  177. return false;
  178. }
  179. protected bool IsAnyPointSelected()
  180. {
  181. foreach(var path in paths)
  182. if (path.selection.Count > 0)
  183. return true;
  184. return false;
  185. }
  186. }
  187. }