void DrawUnselectedKnots()
    {
        for (int i = 0; i < spline.KnotCount; i++)
        {
            if (selectedKnots.Contains(i))
            {
                continue;
            }
            Bezier3DSpline.Knot knot = spline.GetKnot(i);

            Vector3 knotWorldPos = spline.transform.TransformPoint(knot.position);
            if (knot.orientation.HasValue)
            {
                Handles.color = Handles.yAxisColor;
                Quaternion rot = spline.transform.rotation * knot.orientation.Value;
                Handles.ArrowHandleCap(0, knotWorldPos, rot * Quaternion.AngleAxis(90, Vector3.left), 0.15f, EventType.Repaint);
            }
            Handles.color = Color.white;
            if (Handles.Button(knotWorldPos, Camera.current.transform.rotation, HandleUtility.GetHandleSize(knotWorldPos) * handleSize, HandleUtility.GetHandleSize(knotWorldPos) * handleSize, Handles.CircleHandleCap))
            {
                SelectKnot(i, Event.current.control);
            }
        }
    }
    void DrawSelectedSplitters()
    {
        Handles.color = Color.white;
        //Start add
        if (!spline.closed && activeKnot == 0)
        {
            Bezier3DCurve curve = spline.GetCurve(0);
            Vector3
                a = spline.transform.TransformPoint(curve.a),
                b = spline.transform.TransformDirection(curve.b.normalized) * 2f;

            float handleScale = HandleUtility.GetHandleSize(a);
            b *= handleScale;
            Handles.DrawDottedLine(a, a - b, 3f);
            if (Handles.Button(a - b, Camera.current.transform.rotation, handleScale * handleSize * 0.4f, handleScale * handleSize * 0.4f, Handles.DotHandleCap))
            {
                Undo.RecordObject(spline, "Add Bezier Point");
                Bezier3DSpline.Knot knot = spline.GetKnot(activeKnot);
                spline.InsertKnot(0, new Bezier3DSpline.Knot(curve.a - (curve.b.normalized * handleScale * 2), Vector3.zero, curve.b.normalized * 0.5f, knot.auto, knot.orientation));
                if (onUpdateSpline != null)
                {
                    onUpdateSpline(spline);
                }
            }
        }

        //End add
        if (!spline.closed && activeKnot == spline.CurveCount)
        {
            Bezier3DCurve curve = spline.GetCurve(spline.CurveCount - 1);
            Vector3
                c             = spline.transform.TransformDirection(curve.c.normalized) * 2f,
                d             = spline.transform.TransformPoint(curve.d);
            float handleScale = HandleUtility.GetHandleSize(d);
            c *= handleScale;
            Handles.DrawDottedLine(d, d - c, 3f);
            if (Handles.Button(d - c, Camera.current.transform.rotation, handleScale * handleSize * 0.4f, handleScale * handleSize * 0.4f, Handles.DotHandleCap))
            {
                Undo.RecordObject(spline, "Add Bezier Point");
                Bezier3DSpline.Knot knot = spline.GetKnot(activeKnot);
                spline.AddKnot(new Bezier3DSpline.Knot(curve.d - (curve.c.normalized * handleScale * 2), curve.c.normalized * 0.5f, Vector3.zero, knot.auto, knot.orientation));
                SelectKnot(spline.CurveCount, false);
                if (onUpdateSpline != null)
                {
                    onUpdateSpline(spline);
                }
            }
        }

        // Prev split
        if (spline.closed || activeKnot != 0)
        {
            Bezier3DCurve curve       = spline.GetCurve(activeKnot == 0 ? spline.CurveCount - 1 : activeKnot - 1);
            Vector3       centerLocal = curve.GetPoint(curve.Dist2Time(curve.length * 0.5f));
            Vector3       center      = spline.transform.TransformPoint(centerLocal);

            Vector3 a           = curve.a + curve.b;
            Vector3 b           = curve.c + curve.d;
            Vector3 ab          = (b - a) * 0.3f;
            float   handleScale = HandleUtility.GetHandleSize(center);

            if (Handles.Button(center, Camera.current.transform.rotation, handleScale * handleSize * 0.4f, handleScale * handleSize * 0.4f, Handles.DotHandleCap))
            {
                Undo.RecordObject(spline, "Add Bezier Point");
                Bezier3DSpline.Knot knot = spline.GetKnot(activeKnot);
                spline.InsertKnot(activeKnot == 0 ? spline.CurveCount : activeKnot, new Bezier3DSpline.Knot(centerLocal, -ab, ab, knot.auto, knot.orientation));
                if (activeKnot == 0)
                {
                    SelectKnot(spline.CurveCount - 1, false);
                }
                if (onUpdateSpline != null)
                {
                    onUpdateSpline(spline);
                }
            }
        }

        // Next split
        if (activeKnot != spline.CurveCount)
        {
            Bezier3DCurve curve       = spline.GetCurve(activeKnot);
            Vector3       centerLocal = curve.GetPoint(curve.Dist2Time(curve.length * 0.5f));
            Vector3       center      = spline.transform.TransformPoint(centerLocal);

            Vector3 a           = curve.a + curve.b;
            Vector3 b           = curve.c + curve.d;
            Vector3 ab          = (b - a) * 0.3f;
            float   handleScale = HandleUtility.GetHandleSize(center);
            if (Handles.Button(center, Camera.current.transform.rotation, handleScale * handleSize * 0.4f, handleScale * handleSize * 0.4f, Handles.DotHandleCap))
            {
                Undo.RecordObject(spline, "Add Bezier Point");
                spline.InsertKnot(activeKnot + 1, new Bezier3DSpline.Knot(centerLocal, -ab, ab));
                SelectKnot(activeKnot + 1, false);
                if (onUpdateSpline != null)
                {
                    onUpdateSpline(spline);
                }
            }
        }
    }
    void DrawSelectedKnot()
    {
        Bezier3DSpline.Knot knot = spline.GetKnot(activeKnot);
        Handles.color = Color.green;

        Vector3 knotWorldPos = spline.transform.TransformPoint(knot.position);

        if (Tools.current == Tool.Move)
        {
            //Position handle
            EditorGUI.BeginChangeCheck();
            knotWorldPos = Handles.PositionHandle(knotWorldPos, Tools.handleRotation);
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(spline, "Edit Bezier Point");
                knot.position = spline.transform.InverseTransformPoint(knotWorldPos);
                spline.SetKnot(activeKnot, knot);
                if (onUpdateSpline != null)
                {
                    onUpdateSpline(spline);
                }
            }
        }
        else if (Tools.current == Tool.Rotate)
        {
            //Draw arrow

            //Rotation handle
            EditorGUI.BeginChangeCheck();
            Quaternion rot = knot.orientation.HasValue ? knot.orientation.Value : Quaternion.identity;
            Handles.color = Handles.yAxisColor;
            Handles.ArrowHandleCap(0, knotWorldPos, rot * Quaternion.AngleAxis(90, Vector3.left), HandleUtility.GetHandleSize(knotWorldPos), EventType.Repaint);
            rot = Handles.RotationHandle(rot, knotWorldPos);
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(spline, "Edit Bezier Point");
                knot.orientation = rot;
                spline.SetKnot(activeKnot, knot);
                if (onUpdateSpline != null)
                {
                    onUpdateSpline(spline);
                }
                Repaint();
            }
        }


        Handles.color = Handles.zAxisColor;

        //In Handle
        if (knot.handleIn != Vector3.zero)
        {
            EditorGUI.BeginChangeCheck();
            Vector3 inHandleWorldPos = spline.transform.TransformPoint(knot.position + knot.handleIn);
            //inHandleWorldPos = Handles.PositionHandle(inHandleWorldPos, Tools.handleRotation);
            if (knot.auto == 0)
            {
                inHandleWorldPos = SmallPositionHandle(inHandleWorldPos, Tools.handleRotation, 0.5f, 1f);
            }
            else
            {
                inHandleWorldPos = SmallPositionHandle(inHandleWorldPos, Tools.handleRotation, 0.5f, 0.5f);
            }
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(spline, "Edit Bezier Handle");
                knot.handleIn = spline.transform.InverseTransformPoint(inHandleWorldPos) - knot.position;
                knot.auto     = 0;
                if (mirror)
                {
                    knot.handleOut = -knot.handleIn;
                }
                spline.SetKnot(activeKnot, knot);
                if (onUpdateSpline != null)
                {
                    onUpdateSpline(spline);
                }
            }
            Handles.DrawLine(knotWorldPos, inHandleWorldPos);
        }


        //outHandle
        if (knot.handleOut != Vector3.zero)
        {
            EditorGUI.BeginChangeCheck();
            Vector3 outHandleWorldPos = spline.transform.TransformPoint(knot.position + knot.handleOut);
            //outHandleWorldPos = Handles.PositionHandle(outHandleWorldPos, Tools.handleRotation);
            if (knot.auto == 0)
            {
                outHandleWorldPos = SmallPositionHandle(outHandleWorldPos, Tools.handleRotation, 0.5f, 1f);
            }
            else
            {
                outHandleWorldPos = SmallPositionHandle(outHandleWorldPos, Tools.handleRotation, 0.5f, 0.5f);
            }
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(spline, "Edit Bezier Handle");
                knot.handleOut = spline.transform.InverseTransformPoint(outHandleWorldPos) - knot.position;
                knot.auto      = 0;
                if (mirror)
                {
                    knot.handleIn = -knot.handleOut;
                }
                spline.SetKnot(activeKnot, knot);
                if (onUpdateSpline != null)
                {
                    onUpdateSpline(spline);
                }
            }
            Handles.DrawLine(knotWorldPos, outHandleWorldPos);
        }

        // Hotkeys
        Event e = Event.current;

        switch (e.type)
        {
        case EventType.KeyDown:
            if (e.keyCode == KeyCode.Delete)
            {
                if (spline.KnotCount > 2)
                {
                    Undo.RecordObject(spline, "Remove Bezier Point");
                    spline.RemoveKnot(activeKnot);
                    SelectKnot(-1, false);
                    if (onUpdateSpline != null)
                    {
                        onUpdateSpline(spline);
                    }
                }
                e.Use();
            }
            if (e.keyCode == KeyCode.Escape)
            {
                SelectKnot(-1, false);
                e.Use();
            }
            break;
        }
    }
    override public void OnInspectorGUI()
    {
        Bezier3DSpline spline = target as Bezier3DSpline;

        ValidateSelected();

        EditorGUILayout.LabelField("Spline settings");

        EditorGUI.indentLevel = 1;

        EditorGUI.BeginChangeCheck();
        int steps = spline.cacheDensity;

        steps = EditorGUILayout.DelayedIntField("Cache density", steps);
        if (EditorGUI.EndChangeCheck())
        {
            spline.SetCacheDensity(steps);
            if (onUpdateSpline != null)
            {
                onUpdateSpline(spline);
            }
        }

        EditorGUI.BeginChangeCheck();
        bool closed = spline.closed;

        closed = EditorGUILayout.Toggle(new GUIContent("Closed", "Generate an extra curve, connecting the final point to the first point."), closed);
        if (EditorGUI.EndChangeCheck())
        {
            spline.SetClosed(closed);
            if (onUpdateSpline != null)
            {
                onUpdateSpline(spline);
            }
            SceneView.RepaintAll();
        }

        Rect position = EditorGUILayout.GetControlRect(false, 19f, EditorStyles.numberField);

        position.xMin += EditorGUIUtility.labelWidth;

        Rect flipRect = new Rect(position.x, position.y, position.width, position.height);

        if (GUI.Button(flipRect, new GUIContent("Flip", "Flip spline direction.")))
        {
            spline.Flip();
            if (onUpdateSpline != null)
            {
                onUpdateSpline(spline);
            }
            SceneView.RepaintAll();
        }


        EditorGUI.indentLevel = 0;

        EditorGUILayout.Space();
        if (activeKnot != -1)
        {
            EditorGUILayout.LabelField("Selected point");
            EditorGUI.indentLevel = 1;
            Bezier3DSpline.Knot knot = spline.GetKnot(activeKnot);

            position       = EditorGUILayout.GetControlRect(false, 19f, EditorStyles.numberField);
            position.xMin += EditorGUIUtility.labelWidth;

            EditorGUI.BeginChangeCheck();
            bool orientation     = knot.orientation != null;
            Rect orientationRect = new Rect(position.x, position.y, position.height, position.height);
            orientation = GUI.Toggle(orientationRect, orientation, new GUIContent("O", "Orientation Anchor"), "Button");
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(spline, "Toggle Bezier Orientation Anchor");
                if (orientation)
                {
                    knot.orientation = Quaternion.identity;
                }
                else
                {
                    knot.orientation = null;
                }
                spline.SetKnot(activeKnot, knot);
                if (onUpdateSpline != null)
                {
                    onUpdateSpline(spline);
                }
                SceneView.RepaintAll();
            }

            EditorGUI.BeginChangeCheck();
            bool auto     = knot.auto != 0f;
            Rect autoRect = new Rect(position.x + position.height + 4, position.y, position.height, position.height);
            auto = GUI.Toggle(autoRect, auto, new GUIContent("A", "Auto Handles"), "Button");
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(spline, "Toggle Bezier Auto Handles");
                if (auto)
                {
                    knot.auto = 0.33f;
                }
                else
                {
                    knot.auto = 0f;
                }
                spline.SetKnot(activeKnot, knot);
                if (onUpdateSpline != null)
                {
                    onUpdateSpline(spline);
                }
                SceneView.RepaintAll();
            }


            if (orientation)
            {
                EditorGUILayout.Space();
                EditorGUI.BeginChangeCheck();
                Vector3 orientationEuler = knot.orientation.Value.eulerAngles;
                orientationEuler = EditorGUILayout.Vector3Field("Orientation", orientationEuler);
                if (EditorGUI.EndChangeCheck())
                {
                    knot.orientation = Quaternion.Euler(orientationEuler);
                    spline.SetKnot(activeKnot, knot);
                    SceneView.RepaintAll();
                }
            }

            if (auto)
            {
                EditorGUILayout.Space();
                EditorGUI.BeginChangeCheck();
                knot.position = EditorGUILayout.Vector3Field("Position", knot.position);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(spline, "Edit Bezier Point");
                    spline.SetKnot(activeKnot, knot);
                    if (onUpdateSpline != null)
                    {
                        onUpdateSpline(spline);
                    }
                    SceneView.RepaintAll();
                }
                EditorGUI.BeginChangeCheck();
                knot.auto = EditorGUILayout.FloatField("Distance", knot.auto);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(spline, "Edit Bezier Point");
                    spline.SetKnot(activeKnot, knot);
                    if (onUpdateSpline != null)
                    {
                        onUpdateSpline(spline);
                    }
                    SceneView.RepaintAll();
                }
            }
            else
            {
                EditorGUILayout.Space();
                EditorGUI.BeginChangeCheck();
                knot.position = EditorGUILayout.Vector3Field("Position", knot.position);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(spline, "Edit Bezier Point");
                    spline.SetKnot(activeKnot, knot);
                    if (onUpdateSpline != null)
                    {
                        onUpdateSpline(spline);
                    }
                    SceneView.RepaintAll();
                }
                EditorGUI.BeginChangeCheck();
                knot.handleIn = EditorGUILayout.Vector3Field("Handle in", knot.handleIn);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(spline, "Edit Bezier Handle");
                    if (mirror)
                    {
                        knot.handleOut = -knot.handleIn;
                    }
                    spline.SetKnot(activeKnot, knot);
                    if (onUpdateSpline != null)
                    {
                        onUpdateSpline(spline);
                    }
                    SceneView.RepaintAll();
                }
                EditorGUI.BeginChangeCheck();
                knot.handleOut = EditorGUILayout.Vector3Field("Handle out", knot.handleOut);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(spline, "Edit Bezier Handle");
                    if (mirror)
                    {
                        knot.handleIn = -knot.handleOut;
                    }
                    spline.SetKnot(activeKnot, knot);
                    if (onUpdateSpline != null)
                    {
                        onUpdateSpline(spline);
                    }
                    SceneView.RepaintAll();
                }
            }
        }
    }