HeavenStudio/Assets/Plugins/BezierSolution/Utilities/BezierWalkerWithTime.cs

127 lines
3.3 KiB
C#

using UnityEngine;
using UnityEngine.Events;
namespace BezierSolution
{
[AddComponentMenu( "Bezier Solution/Bezier Walker With Time" )]
[HelpURL( "https://github.com/yasirkula/UnityBezierSolution" )]
public class BezierWalkerWithTime : BezierWalker
{
public BezierSpline spline;
public TravelMode travelMode;
public float travelTime = 5f;
[SerializeField]
[Range( 0f, 1f )]
private float m_normalizedT = 0f;
public bool highQuality = false;
public override BezierSpline Spline { get { return spline; } }
public override float NormalizedT
{
get { return m_normalizedT; }
set { m_normalizedT = value; }
}
public float movementLerpModifier = 10f;
public float rotationLerpModifier = 10f;
public LookAtMode lookAt = LookAtMode.Forward;
private bool isGoingForward = true;
public override bool MovingForward { get { return isGoingForward; } }
public UnityEvent onPathCompleted = new UnityEvent();
private bool onPathCompletedCalledAt1 = false;
private bool onPathCompletedCalledAt0 = false;
private void Update()
{
Execute( Time.deltaTime );
}
public override void Execute( float deltaTime )
{
float _normalizedT = highQuality ? spline.evenlySpacedPoints.GetNormalizedTAtPercentage( m_normalizedT ) : m_normalizedT;
transform.position = Vector3.Lerp( transform.position, spline.GetPoint( _normalizedT ), movementLerpModifier * deltaTime );
if( lookAt == LookAtMode.Forward )
{
BezierSpline.Segment segment = spline.GetSegmentAt( _normalizedT );
Quaternion targetRotation;
if( isGoingForward )
targetRotation = Quaternion.LookRotation( segment.GetTangent(), segment.GetNormal() );
else
targetRotation = Quaternion.LookRotation( -segment.GetTangent(), segment.GetNormal() );
transform.rotation = Quaternion.Lerp( transform.rotation, targetRotation, rotationLerpModifier * deltaTime );
}
else if( lookAt == LookAtMode.SplineExtraData )
transform.rotation = Quaternion.Lerp( transform.rotation, spline.GetExtraData( _normalizedT, extraDataLerpAsQuaternionFunction ), rotationLerpModifier * deltaTime );
if( isGoingForward )
{
m_normalizedT += deltaTime / travelTime;
if( m_normalizedT > 1f )
{
if( travelMode == TravelMode.Once )
m_normalizedT = 1f;
else if( travelMode == TravelMode.Loop )
m_normalizedT -= 1f;
else
{
m_normalizedT = 2f - m_normalizedT;
isGoingForward = false;
}
if( !onPathCompletedCalledAt1 )
{
onPathCompletedCalledAt1 = true;
#if UNITY_EDITOR
if( UnityEditor.EditorApplication.isPlaying )
#endif
onPathCompleted.Invoke();
}
}
else
{
onPathCompletedCalledAt1 = false;
}
}
else
{
m_normalizedT -= deltaTime / travelTime;
if( m_normalizedT < 0f )
{
if( travelMode == TravelMode.Once )
m_normalizedT = 0f;
else if( travelMode == TravelMode.Loop )
m_normalizedT += 1f;
else
{
m_normalizedT = -m_normalizedT;
isGoingForward = true;
}
if( !onPathCompletedCalledAt0 )
{
onPathCompletedCalledAt0 = true;
#if UNITY_EDITOR
if( UnityEditor.EditorApplication.isPlaying )
#endif
onPathCompleted.Invoke();
}
}
else
{
onPathCompletedCalledAt0 = false;
}
}
}
}
}