using UnityEngine; using UnityEngine.UIElements; using UnityEngine.Splines; #if !UNITY_2022_1_OR_NEWER using UnityEditor.UIElements; #endif namespace UnityEditor.Splines { sealed class BezierKnotDrawer : ElementDrawer { static readonly string k_PositionTooltip = L10n.Tr("Knot Position"); static readonly string k_RotationTooltip = L10n.Tr("Knot Rotation"); readonly Float3PropertyField m_Position; readonly Float3PropertyField m_Rotation; readonly TangentModePropertyField m_Mode; readonly BezierTangentPropertyField m_BezierMode; readonly TangentPropertyField m_TangentIn; readonly TangentPropertyField m_TangentOut; public BezierKnotDrawer() { VisualElement row; Add(row = new VisualElement(){name = "Vector3WithIcon"}); row.tooltip = k_PositionTooltip; row.style.flexDirection = FlexDirection.Row; row.Add(new VisualElement(){name = "PositionIcon"}); row.Add(m_Position = new Float3PropertyField("", (knot) => knot.LocalPosition, (knot, value) => knot.LocalPosition = value) { name = "Position" }); m_Position.style.flexGrow = 1; Add(row = new VisualElement(){name = "Vector3WithIcon"}); row.tooltip = k_RotationTooltip; row.style.flexDirection = FlexDirection.Row; row.Add(new VisualElement(){name = "RotationIcon"}); row.Add(m_Rotation = new Float3PropertyField("", (knot) => ((Quaternion)knot.LocalRotation).eulerAngles, (knot, value) => knot.LocalRotation = Quaternion.Euler(value)) { name = "Rotation" }); m_Rotation.style.flexGrow = 1; Add(new Separator()); Add(m_Mode = new TangentModePropertyField()); m_Mode.changed += Update; Add(m_BezierMode = new BezierTangentPropertyField()); m_BezierMode.changed += Update; Add(m_TangentIn = new TangentPropertyField("In", "TangentIn", BezierTangent.In)); Add(m_TangentOut = new TangentPropertyField("Out", "TangentOut", BezierTangent.Out)); //Update opposite to take into account some tangent modes m_TangentIn.changed += () => m_TangentOut.Update(targets); m_TangentOut.changed += () => m_TangentIn.Update(targets); } public override string GetLabelForTargets() { if (targets.Count > 1) return $"({targets.Count}) Knots selected"; return $"Knot {target.KnotIndex} (Spline {target.SplineInfo.Index}) selected"; } public override void Update() { base.Update(); m_Position.Update(targets); m_Rotation.Update(targets); m_Mode.Update(targets); m_BezierMode.Update(targets); m_TangentIn.Update(targets); m_TangentOut.Update(targets); //Disabling edition when using linear tangents UpdateTangentsState(); } void UpdateTangentsState() { bool tangentsModifiable = true; bool tangentsBroken = true; bool tangentInSelectable = false; bool tangentOutSelectable = false; for (int i = 0; i < targets.Count; ++i) { var mode = targets[i].Mode; tangentsModifiable &= SplineUtility.AreTangentsModifiable(mode); tangentsBroken &= mode == TangentMode.Broken; tangentInSelectable |= SplineSelectionUtility.IsSelectable(targets[i].TangentIn); tangentOutSelectable |= SplineSelectionUtility.IsSelectable(targets[i].TangentOut); } m_TangentIn.SetEnabled(tangentsModifiable && tangentInSelectable); m_TangentOut.SetEnabled(tangentsModifiable && tangentOutSelectable); if(tangentsModifiable) { m_TangentIn.vector3field.SetEnabled(tangentsBroken); m_TangentOut.vector3field.SetEnabled(tangentsBroken); } } } }