Created
July 24, 2023 10:16
-
-
Save Eraile/fedf977c460a9565a8d61785cba8c81f to your computer and use it in GitHub Desktop.
Spline Follower for Unity, based on Unity's official Spline package
This file contains hidden or 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
/* | |
* Spline Follower for Unity, based on Unity's official Spline package | |
* | |
* Developed by Pierre Mercy | |
* Assisted by OpenAI's GPT-4 Language Model (ChatGPT) | |
* | |
* This script allows an object to follow a spline path in Unity. | |
* It includes various features like speed control, time-based motion, loop, ping pong, and ease in and out functionality. | |
* | |
* The script was developed using Unity 2022 and the Splines 2.3.0 package. | |
* However, it should be compatible with other versions with little to no changes. | |
* | |
* For any issues, you can reach out to Pierre Mercy at http://www.nomercy-studios.com | |
* For any issues related to the AI-assisted part of the code, you can refer to https://www.openai.com/ | |
* | |
*/ | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.Rendering; | |
using UnityEngine.Splines; | |
public class SplineFollower : MonoBehaviour | |
{ | |
[Header("Spline")] | |
[SerializeField] private SplineContainer splineContainer = null; | |
public SplineContainer SplineContainer | |
{ | |
get | |
{ | |
if (this.splineContainer == null) | |
this.splineContainer = this.GetComponent<SplineContainer>(); | |
return this.splineContainer; | |
} | |
} | |
public Spline Spline | |
{ | |
get | |
{ | |
if (this.SplineContainer == null) | |
return null; | |
return this.SplineContainer.Spline; | |
} | |
} | |
[Header("Behaviour - Speed-based")] | |
public bool useSpeed = true; | |
public float speed = 1.0f; | |
[Header("Behaviour - Time-based")] | |
public float timeToReachEnd = 0.0f; // Time in seconds to reach the end of the spline, if greater than 0 speed is ignored | |
[Header("Behaviour - Smoothing")] | |
public bool loop = true; | |
public bool pingPong = false; | |
public bool easeInAndOut = false; // Ease in and out functionality | |
[Header("Progress")] | |
[SerializeField] private float progress = 0.0f; | |
[SerializeField] private bool isForward = true; | |
private void Start() | |
{ | |
//// Optional, uncomment this or apply it another way so that time is used to determine the speed we need to travel at. | |
//if (timeToReachEnd > 0) | |
//{ | |
// speed = Spline.GetLength() / timeToReachEnd; | |
//} | |
} | |
void Update() | |
{ | |
if (Spline != null) | |
{ | |
// Velocity | |
float velocity = Time.deltaTime * speed; | |
// Motion direction | |
float motionDirection = (isForward == true ? 1f : -1f); | |
// Determine progress here | |
if (useSpeed == true || this.timeToReachEnd < 0f) | |
{ | |
progress += (motionDirection * (velocity / Spline.GetLength())); | |
} | |
else | |
{ | |
progress += (motionDirection * (Time.deltaTime / this.timeToReachEnd)); | |
} | |
// Handle looping & pingpong | |
if (progress > 1.0f || progress < 0.0f) | |
{ | |
if (loop) | |
{ | |
progress = Mathf.Repeat(progress, 1.0f); | |
} | |
else if (pingPong) | |
{ | |
isForward = !isForward; | |
progress = Mathf.Clamp01(progress); | |
} | |
else | |
{ | |
progress = Mathf.Clamp01(progress); | |
enabled = false; // stop moving if not looping or ping-ponging | |
} | |
} | |
// If easeInAndOut is true, use the Smoothstep function to ease the motion | |
float easedProgress = easeInAndOut ? Smoothstep(progress) : progress; | |
// Calculate position | |
Vector3 estimationPosition = this.SplineContainer.EvaluatePosition(easedProgress); | |
// Apply position | |
transform.position = Vector3.Lerp(transform.position, estimationPosition, Time.deltaTime * speed); | |
} | |
} | |
// The Smoothstep function for easing | |
float Smoothstep(float x) | |
{ | |
return x * x * (3 - 2 * x); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment