Unity - Simplifying Movement with the "Splines" System

:::note warn
**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).  
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042593/eed4760a-c2ae-4d15-b405-f4f39f0a621f.png)[^1]  
***  

### 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.)  
![Screenshot 2025-03-23 173833.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042593/7cbde08a-d1fe-465e-9ec0-4f5ac3a21c24.png)  

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](https://unity.com/en/blog/engine-platform/building-better-paths-with-splines-in-2022-2 "Building Better Paths with Splines in Unity 2022.2").  

### Moving an Object Along a Spline  

To move an object along a spline:  
1. Click the `Add Component` button in the `Inspector` tab of the **object you want to move**, and search for `Spline Animate`.  
2. 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 Script[^4]  

Here’s a basic script for moving objects along a spline:  

```c#:SplineSystem.cs
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);
    }
}
```

:::note warn
**Warning**  
When handling splines via scripts, make sure to include:  
```c#
using UnityEngine.Splines;
```
:::

If you’re wondering what `[SerializeField]` is, refer

https://qiita.com/Cotorain/items/d9ff9c2611ef38964bdb

Change the `SplinePosition` value to move objects, and the rotation along the spline should also be applied.  
For the detailed mechanism, see the linq;

https://nekojara.city/unity-splines-script

### 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:  
```c#
CalculateLength();
```

Here’s a sample script:  

```c#:SplineSystem.cs
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️⃣  

:::note warn
**Warning**  
The script assumes a `1m = 1 Unity Unit` scale.  
:::

Here’s a script to move objects at a specified speed (km/h):  

```c#:SplineSystem.cs
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

[^1]: Image and reference: [Unity 2022.2 の Splines を使って、フロー状態でより美しいパスを描き出そう](https://unity.com/en/blog/engine-platform/building-better-paths-with-splines-in-2022-2 "Building Better Paths with Splines in Unity 2022.2")  
[^2]: Quote: [Unity 2022 新機能！スプラインを使ってみよう！ - YouTube](https://www.youtube.com/watch?v=5IrKqVnvP6M)  
[^3]: Detailed methods: [【Unity2022】スプラインツールの導入方法と使い方｜ねこじゃらシティ](https://nekojara.city/unity-splines-intro)
[^4]:Reference：[【Unity2022】スプラインをスクリプトから扱う方法｜ねこじゃらシティ](https://nekojara.city/unity-splines-script "【Unity2022】スプラインをスクリプトから扱う方法｜ねこじゃらシティ")