Warning
The information provided here is subject to change. Please refer to official information when updates occur.
This article targets version 2.7 (the functionality may not differ much).
Talking About Splines
The Splines
functionality is part of Unity’s official package. It was released in January 2022, and as of March 2025 (when this article was written), version 2.8 has been released.
Apparently, there were many requests for this feature to be included as a standard function.
Users had been requesting this functionality as part of the standard features for a long time. Now, it’s finally available as an official package.2
Let’s Use Splines
First, install Splines. Open the Package Manager and search for Splines
.
You’ll see a screen like the one below—click the Install
button circled in red. (Since I’ve already loaded Splines, my display may look different.)
After importing, right-click on the hierarchy or select GameObject
and then Spline > New Spline
. Write the spline in the scene and press the Enter
key to finish.
For additional methods, refer to this link.
Moving an Object Along a Spline
To move an object along a spline:
- Click the
Add Component
button in theInspector
tab of the object you want to move, and search forSpline Animate
. - Attach the spline created earlier to the Spline section.
Run it, and the object should move along the spline.3
Creating Your Own Script
In the previous section, we used pre-programmed scripts to move objects. But how about creating your own script to move objects along a spline? Let’s get started!
Moving a Spline with a Script4
Here’s a basic script for moving objects along a spline:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Splines;
public class SplineSystem : MonoBehaviour
{
[SerializeField] private SplineContainer splineContainer;
[SerializeField] private Transform _followTarget; // Add the object (specifically its position data: transform) to follow the spline.
[SerializeField] private float SplinesPercentage;
[SerializeField] private Vector3 AddUpPosition; // Additional functionality.
void Update()
{
if (splineContainer == null || _followTarget == null)
return;
// Update position.
Vector3 position = splineContainer.EvaluatePosition(SplinesPercentage);
position += AddUpPosition; // Add the specified vector (subtract if the value is negative).
_followTarget.position = position;
// Update rotation.
Vector3 tangent = ((Vector3)splineContainer.EvaluateTangent(SplinesPercentage)).normalized;
Vector3 up = ((Vector3)splineContainer.EvaluateUpVector(SplinesPercentage));
_followTarget.rotation = Quaternion.LookRotation(tangent, up);
}
}
Warning
When handling splines via scripts, make sure to include:
using UnityEngine.Splines;
If you’re wondering what [SerializeField]
is, refer
Change the SplinePosition
value to move objects, and the rotation along the spline should also be applied.
For the detailed mechanism, see the linq;
Enhancing the Previous Script
Here, we’ll introduce:
1️⃣ A script where you input a distance from the starting point on the spline to move the object there.
2️⃣ A script where you input a speed (km/h) to move the object along the spline at that speed.
Enhancing the Script: Part 1️⃣
The previous script calculates positions based on percentages.
So, if you know the total length of the spline, can’t you figure out the distance from the starting point?
The function to calculate the spline’s length is:
CalculateLength();
Here’s a sample script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Splines;
public class SplineSystem : MonoBehaviour
{
[SerializeField] private SplineContainer splineContainer;
[SerializeField] private Transform _followTarget;
private float SplinesPercentage; // Change: fully private.
[SerializeField] private float SplineLength_Position; // Add: input distance from the starting point on the spline.
/*[SerializeField]*/ private float SplineLength; // Add: variable for the length of the specified spline.
[SerializeField] private Vector3 AddUpPosition;
[SerializeField] private float AddLength; // Extra functionality.
public TrainSystem trainSystem;
void Start()
{
SplineLength = splineContainer.CalculateLength(); // Add: get the length of the specified spline.
}
void Update()
{
if (splineContainer == null || _followTarget == null)
return;
SplinesPercentage = (SplineLength_Position + AddLength) / SplineLength; // Add: convert distance to percentage and assign to the position variable.
// Update position.
Vector3 position = splineContainer.EvaluatePosition(SplinesPercentage);
position += AddUpPosition; // Add the specified vector (subtract if the value is negative).
_followTarget.position = position;
// Update rotation.
Vector3 tangent = ((Vector3)splineContainer.EvaluateTangent(SplinesPercentage)).normalized;
Vector3 up = ((Vector3)splineContainer.EvaluateUpVector(SplinesPercentage));
_followTarget.rotation = Quaternion.LookRotation(tangent, up);
}
}
Enhancing the Script: Part 2️⃣
Warning
The script assumes a 1m = 1 Unity Unit
scale.
Here’s a script to move objects at a specified speed (km/h):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Splines;
public class SplineSystem : MonoBehaviour
{
[SerializeField] private SplineContainer splineContainer;
[SerializeField] private Transform _followTarget;
private float SplinesPercentage;
[SerializeField] private float SplineLength_Position;
/*[SerializeField]*/ private float SplineLength;
[SerializeField] private Vector3 AddUpPosition;
[SerializeField] private float AddLength;
[SerializeField] private float ObjectSpeed; // Add: insert speed in km/h.
void Start()
{
SplineLength = splineContainer.CalculateLength();
}
void Update()
{
if (splineContainer == null || _followTarget == null)
return;
SplineLength_Position += (ObjectSpeed * (1000f / 3600f)) * Time.deltaTime; // Add: convert km/h to m/s and calculate.
SplinesPercentage = (SplineLength_Position + AddLength) / SplineLength;
// Update position.
Vector3 position = splineContainer.EvaluatePosition(SplinesPercentage);
position += AddUpPosition; // Add the specified vector (subtract if the value is negative).
_followTarget.position = position;
// Update rotation.
Vector3 tangent = ((Vector3)splineContainer.EvaluateTangent(SplinesPercentage)).normalized;
Vector3 up = ((Vector3)splineContainer.EvaluateUpVector(SplinesPercentage));
_followTarget.rotation = Quaternion.LookRotation(tangent, up);
}
}
Final Remarks
Thank you for reading this article! Personally, I just finished my school graduation ceremony and wrote this while relaxing.
I’m preparing for exams soon—ugh—but it’s part of life, isn’t it? To fellow examinees out there—be it primary, junior, or senior high school—let’s work hard together!
The end!
translated with Bing AI
-
Image and reference: Unity 2022.2 の Splines を使って、フロー状態でより美しいパスを描き出そう ↩
-
Detailed methods: 【Unity2022】スプラインツールの導入方法と使い方|ねこじゃらシティ ↩
-
Reference:【Unity2022】スプラインをスクリプトから扱う方法|ねこじゃらシティ ↩