123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- using System;
- using UnityEngine;
- using UnityEngine.U2D;
- using UnityEditor;
- using UnityEditor.U2D.Common.Path;
- using UnityEditor.EditorTools;
- using UnityEditor.ShortcutManagement;
- using UnityEditor.U2D.Common;
-
- namespace UnityEditor.U2D.SpriteShapeInternal
- {
- internal class CustomDrawer : IDrawer
- {
- private IDrawer m_Drawer = new Drawer();
- private SpriteShapeController m_SpriteShapeController;
-
- public CustomDrawer(SpriteShapeController spriteShapeController)
- {
- m_SpriteShapeController = spriteShapeController;
- }
-
- private int GetSubDivisionCount()
- {
- return m_SpriteShapeController.splineDetail;
- }
-
- void IDrawer.DrawBezier(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, float width, Color color)
- {
- Handles.color = color;
- Handles.DrawAAPolyLine(null, width, Handles.MakeBezierPoints(p1, p4, p2, p3, GetSubDivisionCount()));
- }
-
- void IDrawer.DrawCreatePointPreview(Vector3 position, Color color)
- {
- m_Drawer.DrawCreatePointPreview(position, color);
- }
-
- void IDrawer.DrawLine(Vector3 p1, Vector3 p2, float width, Color color)
- {
- m_Drawer.DrawLine(p1, p2, width, color);
- }
-
- void IDrawer.DrawPoint(Vector3 position, Color color)
- {
- m_Drawer.DrawPoint(position, color);
- }
-
- void IDrawer.DrawPointHovered(Vector3 position, Color color)
- {
- m_Drawer.DrawPointHovered(position, color);
- }
-
- void IDrawer.DrawPointSelected(Vector3 position, Color color)
- {
- m_Drawer.DrawPointSelected(position, color);
- }
-
- void IDrawer.DrawTangent(Vector3 position, Vector3 tangent, Color color)
- {
- m_Drawer.DrawTangent(position, tangent, color);
- }
- }
-
- [Serializable]
- internal class SpriteShapeData
- {
- public float height = 1f;
- public int spriteIndex;
- public int corner = 1;
- public int cornerMode = 1;
- }
-
- internal class ScriptableSpriteShapeData : ScriptableData<SpriteShapeData> { }
-
- [CanEditMultipleObjects]
- [CustomEditor(typeof(ScriptableSpriteShapeData))]
- internal class SpriteShapeDataInspector : Editor
- {
- private static class Contents
- {
- public static readonly GUIContent heightLabel = new GUIContent("Height", "Height override for control point.");
- public static readonly GUIContent cornerLabel = new GUIContent("Corner", "Set if Corner is automatic or disabled.");
-
- public static readonly int[] cornerValues = { 0, 1, 2 };
- public static readonly GUIContent[] cornerOptions = { new GUIContent("Disabled"), new GUIContent("Automatic"), new GUIContent("Stretched"), };
- }
-
- private SerializedProperty m_Data;
- private SerializedProperty m_HeightProperty;
- private SerializedProperty m_CornerProperty;
- private SerializedProperty m_CornerModeProperty;
-
- private void OnEnable()
- {
- m_Data = serializedObject.FindProperty("m_Data");
- m_HeightProperty = m_Data.FindPropertyRelative("height");
- m_CornerProperty = m_Data.FindPropertyRelative("corner");
- m_CornerModeProperty = m_Data.FindPropertyRelative("cornerMode");
- }
-
- internal void OnHeightChanged(UnityEngine.Object[] targets, float height)
- {
- foreach (var t in targets)
- {
- var shapeData = t as ScriptableSpriteShapeData;
- var path = SpriteShapeEditorTool.activeSpriteShapeEditorTool.GetPath(shapeData.owner);
-
- if (path.selection.Count == 0)
- continue;
-
- path.undoObject.RegisterUndo("Set Height");
-
- for (var i = 0; i < path.pointCount; ++i)
- {
- if (!path.selection.Contains(i))
- continue;
-
- var data = path.data[i] as SpriteShapeData;
- data.height = height;
- }
-
- SpriteShapeEditorTool.activeSpriteShapeEditorTool.SetPath(shapeData.owner);
- }
- }
-
- internal void OnCornerModeChanged(UnityEngine.Object[] targets, int cornerValue)
- {
- foreach (var t in targets)
- {
- var shapeData = t as ScriptableSpriteShapeData;
- var path = SpriteShapeEditorTool.activeSpriteShapeEditorTool.GetPath(shapeData.owner);
-
- if (path.selection.Count == 0)
- continue;
-
- path.undoObject.RegisterUndo("Set Corner Mode");
-
- for (var i = 0; i < path.pointCount; ++i)
- {
- if (!path.selection.Contains(i))
- continue;
-
- var data = path.data[i] as SpriteShapeData;
- data.cornerMode = cornerValue;
- data.corner = cornerValue != 0 ? 1 : 0;
- }
-
- SpriteShapeEditorTool.activeSpriteShapeEditorTool.SetPath(shapeData.owner);
- }
- }
-
- public override void OnInspectorGUI()
- {
- var scriptableSpriteShapeData = target as ScriptableSpriteShapeData;
- if (!scriptableSpriteShapeData)
- return;
-
- serializedObject.Update();
-
- EditorGUI.BeginChangeCheck();
- var heightValue = EditorGUILayout.Slider(Contents.heightLabel, m_HeightProperty.floatValue, 0.1f, 4.0f);
- if (EditorGUI.EndChangeCheck())
- {
- m_HeightProperty.floatValue = heightValue;
- if (serializedObject.isEditingMultipleObjects)
- OnHeightChanged(targets, heightValue);
- }
-
- EditorGUI.BeginChangeCheck();
- var cornerValue = EditorGUILayout.IntPopup(Contents.cornerLabel, m_CornerModeProperty.intValue, Contents.cornerOptions, Contents.cornerValues);
- if (EditorGUI.EndChangeCheck())
- {
- m_CornerModeProperty.intValue = cornerValue;
- m_CornerProperty.intValue = cornerValue != 0 ? 1 : 0;
- if (serializedObject.isEditingMultipleObjects)
- OnCornerModeChanged(targets, cornerValue);
- }
-
- serializedObject.ApplyModifiedProperties();
- }
- }
-
- internal class CustomPath : GenericScriptablePath<SpriteShapeData> { }
-
- [CanEditMultipleObjects]
- [CustomEditor(typeof(CustomPath))]
- internal class CustomPathInspector : GenericScriptablePathInspector<ScriptableSpriteShapeData, SpriteShapeData> { }
-
- [EditorTool("Edit SpriteShape", typeof(SpriteShapeController))]
- internal class SpriteShapeEditorTool : PathEditorTool<CustomPath>
- {
- private static InternalEditorBridge.ShortcutContext m_ShortcutContext;
-
- public static SpriteShapeEditorTool activeSpriteShapeEditorTool
- {
- get
- {
- if (m_ShortcutContext != null)
- return m_ShortcutContext.context as SpriteShapeEditorTool;
- return null;
- }
- }
-
- protected override bool GetLinearTangentIsZero(UnityEngine.Object target)
- {
- return true;
- }
-
- protected override IDrawer GetCustomDrawer(UnityEngine.Object target)
- {
- return new CustomDrawer(target as SpriteShapeController);
- }
-
- protected override IShape GetShape(UnityEngine.Object target)
- {
- return Polygon.empty;
- }
-
- protected override void Initialize(CustomPath shapeEditor, SerializedObject serializedObject)
- {
- var controller = serializedObject.targetObject as SpriteShapeController;
- var spline = controller.spline;
- shapeEditor.shapeType = ShapeType.Spline;
- shapeEditor.isOpenEnded = spline.isOpenEnded;
-
- for (var i = 0; i < spline.GetPointCount(); ++i)
- {
- var position = spline.GetPosition(i);
-
- shapeEditor.AddPoint(new ControlPoint()
- {
- position = spline.GetPosition(i),
- localLeftTangent = spline.GetLeftTangent(i),
- localRightTangent = spline.GetRightTangent(i),
- tangentMode = (TangentMode)spline.GetTangentMode(i)
- });
-
- shapeEditor.SetData(i, new SpriteShapeData()
- {
- spriteIndex = spline.GetSpriteIndex(i),
- height = spline.GetHeight(i),
- cornerMode = (int)spline.GetCornerMode(i),
- corner = spline.GetCorner(i) ? 1 : 0,
- });
- }
-
- shapeEditor.UpdateTangentsFromMode();
- }
-
- protected override void SetShape(CustomPath shapeEditor, SerializedObject serializedObject)
- {
- serializedObject.Update();
-
- var controller = serializedObject.targetObject as SpriteShapeController;
- var splineProp = serializedObject.FindProperty("m_Spline");
- var controlPointsProp = splineProp.FindPropertyRelative("m_ControlPoints");
-
- splineProp.FindPropertyRelative("m_IsOpenEnded").boolValue = shapeEditor.isOpenEnded;
-
- controlPointsProp.arraySize = shapeEditor.pointCount;
-
- for (var i = 0; i < shapeEditor.pointCount; ++i)
- {
- var elementProp = controlPointsProp.GetArrayElementAtIndex(i);
- var point = shapeEditor.GetPoint(i);
- var data = shapeEditor.GetData(i);
-
- elementProp.FindPropertyRelative("position").vector3Value = point.position;
- elementProp.FindPropertyRelative("leftTangent").vector3Value = point.localLeftTangent;
- elementProp.FindPropertyRelative("rightTangent").vector3Value = point.localRightTangent;
- elementProp.FindPropertyRelative("mode").enumValueIndex = (int)point.tangentMode;
- elementProp.FindPropertyRelative("height").floatValue = data.height;
- elementProp.FindPropertyRelative("spriteIndex").intValue = data.spriteIndex;
- elementProp.FindPropertyRelative("corner").intValue = data.corner;
- elementProp.FindPropertyRelative("m_CornerMode").intValue = data.cornerMode;
- }
-
- serializedObject.ApplyModifiedProperties();
- }
-
- protected override void OnActivate()
- {
-
- }
-
- protected override void OnDeactivate()
- {
-
- }
-
- private void CycleSpriteIndex()
- {
- foreach(var target in targets)
- {
- var spriteShapeController = target as SpriteShapeController;
- var shapeEditor = GetPath(target);
- Editor cachedEditor = null;
- Editor.CreateCachedEditor(spriteShapeController, typeof(SpriteShapeControllerEditor), ref cachedEditor);
- if (spriteShapeController == null || spriteShapeController.spriteShape == null || shapeEditor.selection.Count == 0 || cachedEditor == null || shapeEditor.selection.Count > 1)
- continue;
-
- var spriteShape = spriteShapeController.spriteShape;
- var scEditor = cachedEditor as SpriteShapeControllerEditor;
- var selected = shapeEditor.selection.elements[0];
-
- if (shapeEditor.selection.Contains(selected))
- {
- shapeEditor.undoObject.RegisterUndo("Cycle Variant");
- var data = shapeEditor.GetData(selected);
-
- var angleRangeIndex = scEditor.GetAngleRange(selected);
- if (angleRangeIndex != -1)
- {
- var angleRange = spriteShape.angleRanges[angleRangeIndex];
- if (angleRange.sprites.Count > 0)
- data.spriteIndex = (data.spriteIndex + 1) % angleRange.sprites.Count;
- shapeEditor.SetData(selected, data);
- }
-
- SetPath(target);
- }
- }
- }
-
- private static float SlopeAngle(Vector2 start, Vector2 end)
- {
- var dir = start - end;
- dir.Normalize();
- var dvup = new Vector2(0, 1f);
- var dvrt = new Vector2(1f, 0);
-
- var dr = Vector2.Dot(dir, dvrt);
- var du = Vector2.Dot(dir, dvup);
- var cu = Mathf.Acos(du);
- var sn = dr >= 0 ? 1.0f : -1.0f;
- var an = cu * Mathf.Rad2Deg * sn;
-
- // Adjust angles when direction is parallel to Up Axis.
- an = (du != 1f) ? an : 0;
- an = (du != -1f) ? an : -180f;
- return an;
- }
-
- private void RegisterShortcuts()
- {
- m_ShortcutContext = new InternalEditorBridge.ShortcutContext()
- {
- isActive = () => GUIUtility.hotControl == 0,
- context = this
- };
-
- InternalEditorBridge.RegisterShortcutContext(m_ShortcutContext);
- }
-
- private void UnregisterShortcuts()
- {
- InternalEditorBridge.UnregisterShortcutContext(m_ShortcutContext);
- m_ShortcutContext = null;
- }
-
- public override void OnActivated()
- {
- RegisterShortcuts();
- }
-
- public override void OnWillBeDeactivated()
- {
- UnregisterShortcuts();
- }
-
- [Shortcut("SpriteShape Editing/Cycle Tangent Mode", typeof(InternalEditorBridge.ShortcutContext), KeyCode.M)]
- private static void ShortcutCycleTangentMode(ShortcutArguments args)
- {
- if (args.context == m_ShortcutContext)
- (m_ShortcutContext.context as SpriteShapeEditorTool).CycleTangentMode();
- }
-
- [Shortcut("SpriteShape Editing/Cycle Variant", typeof(InternalEditorBridge.ShortcutContext), KeyCode.N)]
- private static void ShortcutCycleSpriteIndex(ShortcutArguments args)
- {
- if (args.context == m_ShortcutContext)
- (m_ShortcutContext.context as SpriteShapeEditorTool).CycleSpriteIndex();
- }
-
- [Shortcut("SpriteShape Editing/Mirror Tangent", typeof(InternalEditorBridge.ShortcutContext), KeyCode.B)]
- private static void ShortcutCycleMirrorTangent(ShortcutArguments args)
- {
- if (args.context == m_ShortcutContext)
- (m_ShortcutContext.context as SpriteShapeEditorTool).MirrorTangent();
- }
- }
- }
|