UnityRef is currently in early development. Some features may be incomplete and/or not functioning.

UNITYREF

Your Pit Stop For Solving ANYTHING in Unity

physics

[Splines] Prevent Jumps During Seamless Path Transitions

Solution

spritesphysicsrenderinganimationscripting

Unity 2022.1.x - Unity 6.3.x

Published 9 days ago

Issue

 Abrupt snapping occurs when a Transform moves between two SplineContainer instances at high velocities. This is usually observed when distanceTraveled is reset upon reaching the end of a segment, causing a position mismatch or a one-frame teleportation to the origin of the next path.

Quick-Fix

To maintain continuity between paths, do not reset your distance value. Instead, update your current spline and subtract the previous spline length from distanceTraveled to preserve the object's relative momentum.

Expand Analysis

The snapping issue during spline transitions often arises when the distanceTraveled property is reset to zero upon switching to a new spline. This reset causes an abrupt change in the object’s position as it effectively teleports to the start of the new spline, losing the continuity of its movement from the previous segment.

To ensure a seamless transition, the accumulated distance relative to the previous spline’s end must be correctly carried forward to the new spline. A smooth transition is achieved by not resetting the distanceTraveled value to zero. Instead, follow these steps:

  1. Detect when the distanceTraveled exceeds the current Spline length.
  2. Assign the reference of your next spline to the active SplineContainer variable.
  3. Subtract the length of the previous Spline from the current distanceTraveled variable.
  4. Recalculate the new length for the active path to ensure future bounds checking remains accurate.

This operation effectively translates the object’s position from the end of the old spline to the corresponding proportional position on the new spline, maintaining continuous movement.

Additional Tips:

  • Use Spline.CalculateLength() to get an accurate float value for the subtraction logic.
  • Ensure both splines have similar knot densities at the connection point to avoid perceptible velocity changes if using non-linear interpolation.
  • If your splines are not physically connected in 3D space, calculate a blending offset between the last knot of the old spline and the first knot of the new spline.

Copy


using UnityEngine;
using UnityEngine.Splines;
using Unity.Mathematics;

public class SplineFollower : MonoBehaviour
{
    public SplineContainer currentSpline;
    public SplineContainer nextSpline;
    public float speed = 5f;
    private float distanceTraveled;

    void Update()
    {
        if (currentSpline == null) return;

        float splineLength = currentSpline.CalculateLength();
        distanceTraveled += speed * Time.deltaTime;

        if (distanceTraveled >= splineLength && nextSpline != null)
        {
            // Transition logic: Carry over the distance to the next spline
            currentSpline = nextSpline;
            distanceTraveled -= splineLength;
            nextSpline = null;
        }

        float3 position = currentSpline.EvaluatePosition(distanceTraveled / currentSpline.CalculateLength());
        transform.position = position;
    }
}

Related Posts Haven't quite found a solution to your problem? We think these posts might help you.

Content inspired by a Unity discussion post.