Splines and Procedural Paths
The built-in Splines package in Unity 6, Bezier/B-Spline curves, Cinemachine SplineDolly, and spawning along a path.
Unity 6 has a built-in Splines package (com.unity.splines). Previously, for rail cameras,
tracks, and AI patrols you had to write Bezier math by hand or install asset-store plugins.
Not anymore.
What the package provides
- SplineContainer — a node container for one or more curves (Catmull-Rom, Bezier, B-Spline).
- Spline Tool in the Scene View — you draw points with the mouse and drag tangents.
- SplineExtrude — extrudes a mesh along a spline (a ready-made road/pipe).
- SplineInstantiate — places prefabs along a curve (fences, posts, trees).
- SplineAnimate — animates a Transform along a spline (moving platforms, AI on rails).
- Cinemachine SplineDolly — a camera on rails.
An SVG path with the M, L, C, Q commands. Or the GSAP MotionPath plugin for animation along a curve.
A Spline stores control points and tangents, and the engine interpolates. EvaluatePosition(t) /
EvaluateTangent(t) give the point and direction at the parameter t ∈ [0, 1].
Basic work with a spline from code
using UnityEngine;
using UnityEngine.Splines;
using Unity.Mathematics;
public class SplineWalker : MonoBehaviour
{
[SerializeField] private SplineContainer container;
[SerializeField] private float speed = 2f;
private float _t;
private void Update() {
_t += Time.deltaTime * speed * (1f / container.CalculateLength());
if (_t > 1f) _t -= 1f;
// EvaluatePosition / EvaluateTangent work with Unity.Mathematics types
float3 pos = container.EvaluatePosition(_t);
float3 tangent = container.EvaluateTangent(_t);
transform.position = pos;
if (math.lengthsq(tangent) > 0.0001f) {
transform.rotation = Quaternion.LookRotation(tangent);
}
}
}
The spline itself is created on a GameObject via Add Component → Spline → Spline Container. Then in the Scene View you enable the Spline Tool (T) and place points.
The parameter t ∈ [0, 1] is the normalized parameter of the spline, not distance. If you just
do _t += Time.deltaTime, the speed will be uneven (faster on short segments).
Divide by CalculateLength() to get a constant speed in m/s.
SplineAnimate — animation without code
If you want the “simple” way: add a SplineAnimate component to the moving object and assign the spline.
Parameters:
- Method — Distance / Time / Linear / Ease in/out.
- Duration / Max Speed — duration or maximum speed.
- Alignment — None / SplineElement / SplineObject / World — how to orient the object.
- Loop — Loop / Ping Pong / Once.
Ideal for moving platforms, elevators, and AI on rails.
SplineInstantiate — placing prefabs
A scene with a fence of 30 posts? Previously you placed them by hand in the editor or wrote a script. Now:
- Make a single post a prefab.
- On the spline, add SplineInstantiate.
- In Items, specify the prefab + density.
- Click Update — Unity multiplies the posts along the curve.
The Spacing (distance between instances), Position Offset Range, and Rotation Offset Range fields
provide randomization for a natural-looking layout.
Cinemachine SplineDolly — a camera on rails
In Cinemachine 3 + Splines there is a ready-made integration:
- In the scene — a
SplineContainer(draw the camera track). - On the
CinemachineCamera, add aCinemachineSplineDolly. - In
Spline, set your SplineContainer. - Camera Position — the parameter t (can be animated via Timeline or Animator).
- Auto Dolly — automatically follows the
Tracking Targetand keeps the camera at the nearest point on the spline.
using Unity.Cinemachine;
public class CutsceneCamera : MonoBehaviour
{
[SerializeField] private CinemachineSplineDolly dolly;
[SerializeField] private float duration = 5f;
private float _t;
public void Play() { _t = 0f; enabled = true; }
private void Update() {
_t += Time.deltaTime / duration;
dolly.CameraPosition = Mathf.Clamp01(_t);
if (_t >= 1f) enabled = false;
}
}
Ideal for intro/outro cutscenes, fly-throughs, and moving the camera through a level.
SplineExtrude — procedural roads and pipes
SplineExtrude takes a 2D cross-section (for example, a circle) and sweeps it along the spline. The
output is a ready-made mesh.
Use cases:
- Roads — a thick rectangular cross-section.
- Pipelines — a circle.
- Cave walls — an irregular mesh segment.
// Parameters in the Inspector:
// - Spline: SplineContainer
// - Radius: the radius of the extruded mesh
// - Sides: the number of cross-section sides (round = 16+)
// - Range: which part of the spline to extrude
// - Segments per Unit: mesh density
Popular patterns
- Snap to spline —
SplineUtility.GetNearestPoint(spline, queryPoint, out float t)finds the nearest point. Used in “snap to road” logic. - Patrol AI along a spline — the enemy patrols via
SplineAnimateinPing Pongmode.EvaluateTangentgives it a direction so it looks forward. - Scrolling parallax — a sprite moves along a spline that provides a non-linear path.
- Cursor over a map — a UI element moves along a drawn route curve.
When NOT to use Splines
- If you only have straight lines — a
Vector3array is cheaper and simpler. - Paths that change dynamically every frame — SplineContainer is not optimized for infinite modification (it works, but slower than custom math).
- Grids of hundreds of splines in a frame — for procedural tracks the Job System is better (see the next chapter).