// --------------------------------------------------------------------------------------------------------------------
//
// Part of: Photon Unity Networking Demos
//
//
// Original: http://catlikecoding.com/unity/tutorials/curves-and-splines/
// Used in SlotRacer Demo
//
// developer@exitgames.com
// --------------------------------------------------------------------------------------------------------------------
using UnityEditor;
using UnityEngine;
namespace Photon.Pun.Demo.SlotRacer.Utils
{
[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 UNITY_5_6_OR_NEWER
if (Handles.Button(point, handleRotation, size * handleSize, size * pickSize, Handles.DotHandleCap))
#else
if (Handles.Button(point, handleRotation, size * handleSize, size * pickSize, Handles.DotCap))
#endif
{
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;
}
}
}