You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.5 KiB

5 years ago
  1. using UnityEditor;
  2. using UnityEngine;
  3. [CustomEditor(typeof(BezierSpline))]
  4. public class BezierSplineInspector : Editor {
  5. private const int stepsPerCurve = 10;
  6. private const float directionScale = 0.5f;
  7. private const float handleSize = 0.04f;
  8. private const float pickSize = 0.06f;
  9. private static Color[] modeColors = {
  10. Color.white,
  11. Color.yellow,
  12. Color.cyan
  13. };
  14. private BezierSpline spline;
  15. private Transform handleTransform;
  16. private Quaternion handleRotation;
  17. private int selectedIndex = -1;
  18. public override void OnInspectorGUI () {
  19. spline = target as BezierSpline;
  20. EditorGUI.BeginChangeCheck();
  21. bool loop = EditorGUILayout.Toggle("Loop", spline.Loop);
  22. if (EditorGUI.EndChangeCheck()) {
  23. Undo.RecordObject(spline, "Toggle Loop");
  24. EditorUtility.SetDirty(spline);
  25. spline.Loop = loop;
  26. }
  27. if (selectedIndex >= 0 && selectedIndex < spline.ControlPointCount) {
  28. DrawSelectedPointInspector();
  29. }
  30. if (GUILayout.Button("Add Curve")) {
  31. Undo.RecordObject(spline, "Add Curve");
  32. spline.AddCurve();
  33. EditorUtility.SetDirty(spline);
  34. }
  35. }
  36. private void DrawSelectedPointInspector() {
  37. GUILayout.Label("Selected Point");
  38. EditorGUI.BeginChangeCheck();
  39. Vector3 point = EditorGUILayout.Vector3Field("Position", spline.GetControlPoint(selectedIndex));
  40. if (EditorGUI.EndChangeCheck()) {
  41. Undo.RecordObject(spline, "Move Point");
  42. EditorUtility.SetDirty(spline);
  43. spline.SetControlPoint(selectedIndex, point);
  44. }
  45. EditorGUI.BeginChangeCheck();
  46. BezierControlPointMode mode = (BezierControlPointMode)EditorGUILayout.EnumPopup("Mode", spline.GetControlPointMode(selectedIndex));
  47. if (EditorGUI.EndChangeCheck()) {
  48. Undo.RecordObject(spline, "Change Point Mode");
  49. spline.SetControlPointMode(selectedIndex, mode);
  50. EditorUtility.SetDirty(spline);
  51. }
  52. }
  53. private void OnSceneGUI () {
  54. spline = target as BezierSpline;
  55. handleTransform = spline.transform;
  56. handleRotation = Tools.pivotRotation == PivotRotation.Local ?
  57. handleTransform.rotation : Quaternion.identity;
  58. Vector3 p0 = ShowPoint(0);
  59. for (int i = 1; i < spline.ControlPointCount; i += 3) {
  60. Vector3 p1 = ShowPoint(i);
  61. Vector3 p2 = ShowPoint(i + 1);
  62. Vector3 p3 = ShowPoint(i + 2);
  63. Handles.color = Color.gray;
  64. Handles.DrawLine(p0, p1);
  65. Handles.DrawLine(p2, p3);
  66. Handles.DrawBezier(p0, p3, p1, p2, Color.white, null, 2f);
  67. p0 = p3;
  68. }
  69. ShowDirections();
  70. }
  71. private void ShowDirections () {
  72. Handles.color = Color.green;
  73. Vector3 point = spline.GetPoint(0f);
  74. Handles.DrawLine(point, point + spline.GetDirection(0f) * directionScale);
  75. int steps = stepsPerCurve * spline.CurveCount;
  76. for (int i = 1; i <= steps; i++) {
  77. point = spline.GetPoint(i / (float)steps);
  78. Handles.DrawLine(point, point + spline.GetDirection(i / (float)steps) * directionScale);
  79. }
  80. }
  81. private Vector3 ShowPoint (int index) {
  82. Vector3 point = handleTransform.TransformPoint(spline.GetControlPoint(index));
  83. float size = HandleUtility.GetHandleSize(point);
  84. if (index == 0) {
  85. size *= 2f;
  86. }
  87. Handles.color = modeColors[(int)spline.GetControlPointMode(index)];
  88. if (Handles.Button(point, handleRotation, size * handleSize, size * pickSize, Handles.DotCap)) {
  89. selectedIndex = index;
  90. Repaint();
  91. }
  92. if (selectedIndex == index) {
  93. EditorGUI.BeginChangeCheck();
  94. point = Handles.DoPositionHandle(point, handleRotation);
  95. if (EditorGUI.EndChangeCheck()) {
  96. Undo.RecordObject(spline, "Move Point");
  97. EditorUtility.SetDirty(spline);
  98. spline.SetControlPoint(index, handleTransform.InverseTransformPoint(point));
  99. }
  100. }
  101. return point;
  102. }
  103. }