|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
[CustomEditor(typeof(BezierSpline))]
|
|
public class BezierSplineInspector : Editor {
|
|
|
|
private const int stepsPerCurve = 10;
|
|
private const float directionScale = 0.5f;
|
|
private const float handleSize = 0.04f;
|
|
private const float pickSize = 0.06f;
|
|
|
|
private static Color[] modeColors = {
|
|
Color.white,
|
|
Color.yellow,
|
|
Color.cyan
|
|
};
|
|
|
|
private BezierSpline spline;
|
|
private Transform handleTransform;
|
|
private Quaternion handleRotation;
|
|
private int selectedIndex = -1;
|
|
|
|
public override void OnInspectorGUI () {
|
|
spline = target as BezierSpline;
|
|
EditorGUI.BeginChangeCheck();
|
|
bool loop = EditorGUILayout.Toggle("Loop", spline.Loop);
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
Undo.RecordObject(spline, "Toggle Loop");
|
|
EditorUtility.SetDirty(spline);
|
|
spline.Loop = loop;
|
|
}
|
|
if (selectedIndex >= 0 && selectedIndex < spline.ControlPointCount) {
|
|
DrawSelectedPointInspector();
|
|
}
|
|
if (GUILayout.Button("Add Curve")) {
|
|
Undo.RecordObject(spline, "Add Curve");
|
|
spline.AddCurve();
|
|
EditorUtility.SetDirty(spline);
|
|
}
|
|
}
|
|
|
|
private void DrawSelectedPointInspector() {
|
|
GUILayout.Label("Selected Point");
|
|
EditorGUI.BeginChangeCheck();
|
|
Vector3 point = EditorGUILayout.Vector3Field("Position", spline.GetControlPoint(selectedIndex));
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
Undo.RecordObject(spline, "Move Point");
|
|
EditorUtility.SetDirty(spline);
|
|
spline.SetControlPoint(selectedIndex, point);
|
|
}
|
|
EditorGUI.BeginChangeCheck();
|
|
BezierControlPointMode mode = (BezierControlPointMode)EditorGUILayout.EnumPopup("Mode", spline.GetControlPointMode(selectedIndex));
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
Undo.RecordObject(spline, "Change Point Mode");
|
|
spline.SetControlPointMode(selectedIndex, mode);
|
|
EditorUtility.SetDirty(spline);
|
|
}
|
|
}
|
|
|
|
private void OnSceneGUI () {
|
|
spline = target as BezierSpline;
|
|
handleTransform = spline.transform;
|
|
handleRotation = Tools.pivotRotation == PivotRotation.Local ?
|
|
handleTransform.rotation : Quaternion.identity;
|
|
|
|
Vector3 p0 = ShowPoint(0);
|
|
for (int i = 1; i < spline.ControlPointCount; i += 3) {
|
|
Vector3 p1 = ShowPoint(i);
|
|
Vector3 p2 = ShowPoint(i + 1);
|
|
Vector3 p3 = ShowPoint(i + 2);
|
|
|
|
Handles.color = Color.gray;
|
|
Handles.DrawLine(p0, p1);
|
|
Handles.DrawLine(p2, p3);
|
|
|
|
Handles.DrawBezier(p0, p3, p1, p2, Color.white, null, 2f);
|
|
p0 = p3;
|
|
}
|
|
ShowDirections();
|
|
}
|
|
|
|
private void ShowDirections () {
|
|
Handles.color = Color.green;
|
|
Vector3 point = spline.GetPoint(0f);
|
|
Handles.DrawLine(point, point + spline.GetDirection(0f) * directionScale);
|
|
int steps = stepsPerCurve * spline.CurveCount;
|
|
for (int i = 1; i <= steps; i++) {
|
|
point = spline.GetPoint(i / (float)steps);
|
|
Handles.DrawLine(point, point + spline.GetDirection(i / (float)steps) * directionScale);
|
|
}
|
|
}
|
|
|
|
private Vector3 ShowPoint (int index) {
|
|
Vector3 point = handleTransform.TransformPoint(spline.GetControlPoint(index));
|
|
float size = HandleUtility.GetHandleSize(point);
|
|
if (index == 0) {
|
|
size *= 2f;
|
|
}
|
|
Handles.color = modeColors[(int)spline.GetControlPointMode(index)];
|
|
if (Handles.Button(point, handleRotation, size * handleSize, size * pickSize, Handles.DotCap)) {
|
|
selectedIndex = index;
|
|
Repaint();
|
|
}
|
|
if (selectedIndex == index) {
|
|
EditorGUI.BeginChangeCheck();
|
|
point = Handles.DoPositionHandle(point, handleRotation);
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
Undo.RecordObject(spline, "Move Point");
|
|
EditorUtility.SetDirty(spline);
|
|
spline.SetControlPoint(index, handleTransform.InverseTransformPoint(point));
|
|
}
|
|
}
|
|
return point;
|
|
}
|
|
}
|