using System.Collections.Generic; using Unity.Mathematics; namespace UnityEngine.Splines { /// /// A Component that holds a object. /// #if UNITY_2021_2_OR_NEWER [Icon(k_IconPath)] #endif [AddComponentMenu("Splines/Spline")] public sealed class SplineContainer : MonoBehaviour, ISplineProvider { const string k_IconPath = "Packages/com.unity.splines/Editor/Resources/Icons/SplineComponent.png"; readonly Spline[] m_SplineArray = new Spline[1]; [SerializeField] Spline m_Spline = new Spline(); IEnumerable ISplineProvider.Splines { get { m_SplineArray[0] = Spline; return m_SplineArray; } } bool IsScaled => transform.lossyScale != Vector3.one; /// /// The instantiated object attached to this component. /// public Spline Spline { get => m_Spline; set => m_Spline = value; } /// /// Compute interpolated position, direction and upDirection at ratio t. Calling this method to get the /// 3 vectors is faster than calling independently EvaluateSplinePosition, EvaluateSplineTangent and EvaluateSplineUpVector /// for the same time t as it reduces some redundant computation. /// /// A value between 0 and 1 representing the ratio along the curve. /// Output variable for the float3 position at t. /// Output variable for the float3 tangent at t. /// Output variable for the float3 up direction at t. /// Boolean value, true if a valid set of output variables as been computed. public bool Evaluate(float t, out float3 position, out float3 tangent, out float3 upVector) { if (Spline == null) { position = float3.zero; tangent = new float3(0, 0, 1); upVector = new float3(0, 1, 0); return false; } if (IsScaled) { using var nativeSpline = new NativeSpline(Spline, transform.localToWorldMatrix); return SplineUtility.Evaluate(nativeSpline, t, out position, out tangent, out upVector); } var evaluationStatus = SplineUtility.Evaluate(Spline, t, out position, out tangent, out upVector); if (evaluationStatus) { position = transform.TransformPoint(position); tangent = transform.TransformVector(tangent); upVector = transform.TransformDirection(upVector); } return evaluationStatus; } /// /// Evaluate a tangent vector on a curve at a specific t in world space. /// /// A value between 0 and 1 representing a percentage of the curve. /// A tangent vector. public float3 EvaluatePosition(float t) { if(Spline == null) return float.PositiveInfinity; if(IsScaled) { using var nativeSpline = new NativeSpline(Spline, transform.localToWorldMatrix); return SplineUtility.EvaluatePosition(nativeSpline, t); } return transform.TransformPoint(SplineUtility.EvaluatePosition(Spline, t)); } /// /// Evaluate a tangent vector at a specific t in world space. /// /// A value between 0 and 1 representing a percentage of entire spline /// A tangent vector public float3 EvaluateTangent(float t) { if (Spline == null) return 0; if(IsScaled) { using var nativeSpline = new NativeSpline(Spline, transform.localToWorldMatrix); return SplineUtility.EvaluateTangent(nativeSpline, t); } return transform.TransformVector(SplineUtility.EvaluateTangent(Spline, t)); } /// /// Evaluate an up vector direction at a specific t /// /// A value between 0 and 1 representing a percentage of entire spline /// An up direction. public float3 EvaluateUpVector(float t) { if (Spline == null) return float.PositiveInfinity; if(IsScaled) { using var nativeSpline = new NativeSpline(Spline, transform.localToWorldMatrix); return SplineUtility.EvaluateUpVector(nativeSpline, t); } //Using TransformDirection as up direction is Not sensible to scale return transform.TransformDirection(SplineUtility.EvaluateUpVector(Spline, t)); } /// /// Evaluate an acceleration vector at a specific t /// /// A value between 0 and 1 representing a percentage of entire spline /// An acceleration vector. public float3 EvaluateAcceleration(float t) { if (Spline == null) return float.PositiveInfinity; if(IsScaled) { using var nativeSpline = new NativeSpline(Spline, transform.localToWorldMatrix); return SplineUtility.EvaluateAcceleration(nativeSpline, t); } return transform.TransformVector(SplineUtility.EvaluateAcceleration(Spline, t)); } /// /// Calculate the length of in world space. /// /// The length of in world space public float CalculateLength() { if(Spline == null) return 0; return SplineUtility.CalculateLength(Spline, transform.localToWorldMatrix); } } }