138 lines
6.4 KiB
C#
138 lines
6.4 KiB
C#
|
using UnityEditor;
|
||
|
using UnityEngine;
|
||
|
using UnityEditor.Sprites;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
|
||
|
namespace UnityEditor.U2D
|
||
|
{
|
||
|
public class AngleRangeGUI
|
||
|
{
|
||
|
public static readonly int kLeftHandleHashCode = "LeftHandle".GetHashCode();
|
||
|
public static readonly int kRightHandleHashCode = "RightHandle".GetHashCode();
|
||
|
public const float kRangeWidth = 10f;
|
||
|
|
||
|
public static void AngleRangeField(Rect rect, ref float start, ref float end, float angleOffset, float radius, bool snap, bool drawLine, bool drawCircle, Color rangeColor)
|
||
|
{
|
||
|
var leftId = GUIUtility.GetControlID(kLeftHandleHashCode, FocusType.Passive);
|
||
|
var rightId = GUIUtility.GetControlID(kRightHandleHashCode, FocusType.Passive);
|
||
|
AngleRangeField(rect, leftId, rightId, ref start, ref end, angleOffset, radius, snap, drawLine, drawCircle, rangeColor);
|
||
|
}
|
||
|
|
||
|
public static void AngleRangeField(Rect rect, int leftHandleID, int rightHandleID, ref float start, ref float end, float angleOffset, float radius, bool snap, bool drawLine, bool drawCircle, Color rangeColor)
|
||
|
{
|
||
|
Color activeColor = Handles.color;
|
||
|
|
||
|
if (Event.current.type == EventType.Repaint)
|
||
|
{
|
||
|
float range = end - start;
|
||
|
|
||
|
Color color = Handles.color;
|
||
|
Handles.color = rangeColor;
|
||
|
if (range < 0f)
|
||
|
Handles.color = Color.red;
|
||
|
|
||
|
SpriteShapeHandleUtility.DrawSolidArc(rect.center, Vector3.forward, Quaternion.AngleAxis(start + angleOffset, Vector3.forward) * Vector3.right, range, radius, kRangeWidth);
|
||
|
Handles.color = color;
|
||
|
}
|
||
|
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
|
||
|
float handleSize = 15f;
|
||
|
|
||
|
start = AngleField(rect, leftHandleID, start, angleOffset, new Vector2(-3.5f, -7.5f), start + angleOffset + 90f, handleSize, radius, snap, drawLine, drawCircle, SpriteShapeHandleUtility.RangeLeftCap);
|
||
|
|
||
|
if (EditorGUI.EndChangeCheck())
|
||
|
start = Mathf.Clamp(start, end - 360f, end);
|
||
|
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
|
||
|
end = AngleField(rect, rightHandleID, end, angleOffset, new Vector2(3.5f, -7.5f), end + angleOffset + 90f, handleSize, radius, snap, drawLine, false, SpriteShapeHandleUtility.RangeRightCap);
|
||
|
|
||
|
if (EditorGUI.EndChangeCheck())
|
||
|
end = Mathf.Clamp(end, end, start + 360f);
|
||
|
|
||
|
Handles.color = activeColor;
|
||
|
}
|
||
|
|
||
|
public static void AngleRangeField(Rect rect, SerializedProperty startProperty, SerializedProperty endProperty, float angleOffset, float radius, bool snap, bool drawLine, bool drawCircle, Color rangeColor)
|
||
|
{
|
||
|
var start = startProperty.floatValue;
|
||
|
var end = endProperty.floatValue;
|
||
|
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
AngleRangeField(rect, ref start, ref end, angleOffset, radius, snap, drawLine, drawCircle, rangeColor);
|
||
|
if (EditorGUI.EndChangeCheck())
|
||
|
{
|
||
|
startProperty.floatValue = start;
|
||
|
endProperty.floatValue = end;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void AngleField(int id, SerializedProperty property, float angleOffset, Vector2 handleOffset, float handleAngle, float handleSize, float radius, bool snap, bool drawLine, bool drawCircle, Handles.CapFunction drawCapFunction)
|
||
|
{
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
float value = AngleField(id, property.floatValue, angleOffset, handleOffset, handleAngle, handleSize, radius, snap, drawLine, drawCircle, drawCapFunction);
|
||
|
if (EditorGUI.EndChangeCheck())
|
||
|
{
|
||
|
property.floatValue = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void AngleField(Rect r, int id, SerializedProperty property, float angleOffset, Vector2 handleOffset, float handleAngle, float handleSize, float radius, bool snap, bool drawLine, bool drawCircle, Handles.CapFunction drawCapFunction)
|
||
|
{
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
float value = AngleField(r, id, property.floatValue, angleOffset, handleOffset, handleAngle, handleSize, radius, snap, drawLine, drawCircle, drawCapFunction);
|
||
|
if (EditorGUI.EndChangeCheck())
|
||
|
{
|
||
|
property.floatValue = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static float AngleField(int id, float angle, float angleOffset, Vector2 handleOffset, float handleAngle, float radius, float handleSize, bool snap, bool drawLine, bool drawCircle, Handles.CapFunction drawCapFunction)
|
||
|
{
|
||
|
Rect rect = EditorGUILayout.GetControlRect(false, radius * 2f);
|
||
|
return AngleField(rect, id, angle, angleOffset, handleOffset, handleAngle, radius, handleSize, snap, drawLine, drawCircle, drawCapFunction);
|
||
|
}
|
||
|
|
||
|
public static float AngleField(Rect rect, int id, float angle, float angleOffset, Vector2 handleOffset, float handleAngle, float handleSize, float radius, bool snap, bool drawLine, bool drawCircle, Handles.CapFunction drawCapFunction)
|
||
|
{
|
||
|
float offsetedAngle = angle + angleOffset;
|
||
|
Vector2 pos = new Vector2(Mathf.Cos(offsetedAngle * Mathf.Deg2Rad), Mathf.Sin(offsetedAngle * Mathf.Deg2Rad)) * radius + rect.center;
|
||
|
|
||
|
if (Event.current.type == EventType.Repaint)
|
||
|
{
|
||
|
if (drawCircle)
|
||
|
Handles.DrawWireDisc(rect.center, Vector3.forward, radius);
|
||
|
|
||
|
if (drawLine)
|
||
|
Handles.DrawLine(rect.center, pos);
|
||
|
}
|
||
|
|
||
|
if (GUI.enabled)
|
||
|
{
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
|
||
|
Quaternion rotation = Quaternion.AngleAxis(handleAngle, Vector3.forward);
|
||
|
Vector2 posNew = SpriteShapeHandleUtility.Slider2D(id, pos, rotation * handleOffset, rotation, handleSize, drawCapFunction);
|
||
|
|
||
|
if (EditorGUI.EndChangeCheck())
|
||
|
{
|
||
|
Vector2 v1 = pos - rect.center;
|
||
|
Vector2 v2 = posNew - rect.center;
|
||
|
|
||
|
float angleDirection = Mathf.Sign(Vector3.Dot(Vector3.forward, Vector3.Cross(v1, v2)));
|
||
|
float angleIncrement = Vector2.Angle(v1, v2);
|
||
|
|
||
|
angle += angleIncrement * angleDirection;
|
||
|
|
||
|
if (snap)
|
||
|
angle = Mathf.RoundToInt(angle);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return angle;
|
||
|
}
|
||
|
}
|
||
|
}
|