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