Created
August 31, 2024 16:14
-
-
Save adammyhre/b81eb6e1d07ebe24a49844fbbddf368b to your computer and use it in GitHub Desktop.
Smooth Follow Spline Auto Dolly for Cinemachine 3.1.1 Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Unity.Cinemachine; | |
using UnityEngine; | |
using UnityEngine.Splines; | |
[Serializable] | |
public class SmoothFollow : SplineAutoDolly.ISplineAutoDolly { | |
[Tooltip("Maximum speed of the dolly along the spline.")] | |
public float MaxSpeed = 0.5f; | |
[Tooltip("How quickly the dolly reacts to the target's movement.")] | |
public float SmoothTime = 2f; | |
[Tooltip("Look-ahead distance to predict target's future position.")] | |
public float LookAheadDistance = 2f; | |
[Tooltip("Distance tolerance to the target before stopping.")] | |
public float StoppingDistance = 0.1f; | |
private float currentVelocity; | |
void SplineAutoDolly.ISplineAutoDolly.Validate() { | |
MaxSpeed = Mathf.Max(0, MaxSpeed); | |
SmoothTime = Mathf.Max(0.01f, SmoothTime); | |
LookAheadDistance = Mathf.Max(0, LookAheadDistance); | |
StoppingDistance = Mathf.Max(0, StoppingDistance); | |
} | |
void SplineAutoDolly.ISplineAutoDolly.Reset() { | |
currentVelocity = 0; | |
} | |
bool SplineAutoDolly.ISplineAutoDolly.RequiresTrackingTarget => true; | |
float SplineAutoDolly.ISplineAutoDolly.GetSplinePosition( | |
MonoBehaviour sender, Transform target, SplineContainer spline, | |
float currentPosition, PathIndexUnit positionUnits, float deltaTime) | |
{ | |
if (target == null || deltaTime <= 0) return currentPosition; | |
// Predict the target's future position based on LookAheadDistance | |
Vector3 targetPosition = target.position + target.forward * LookAheadDistance; | |
Vector3 localTargetPos = spline.transform.InverseTransformPoint(targetPosition); | |
// Find the nearest point on the spline to the predicted target position | |
SplineUtility.GetNearestPoint(spline.Spline, localTargetPos, out _, out var normalizedPos, 10, 3); | |
normalizedPos = Mathf.Clamp01(normalizedPos); | |
float targetPositionOnSpline = spline.Spline.ConvertIndexUnit(normalizedPos, PathIndexUnit.Normalized, positionUnits); | |
// Compute the distance between the current and target positions | |
float distanceToTarget = Mathf.Abs(targetPositionOnSpline - currentPosition); | |
// Check if within the stopping distance | |
if (distanceToTarget < StoppingDistance) return currentPosition; | |
// Smoothly interpolate to the target position | |
return Mathf.SmoothDamp(currentPosition, targetPositionOnSpline, ref currentVelocity, SmoothTime, MaxSpeed, deltaTime); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment