Actor travel along spline at constant speed?

I’m having some issues getting an actor to move along a spline at a fixed speed.

I’m generating the spline like this:

local InterpCurveVector splinePath;
local InterpCurvePointVector splinePoint;
local Array<vector> flightPathVectors;

//Add the path i want for generate the spline from.
flightPathVectors.AddItem(someVector1);
flightPathVectors.AddItem(someVector2);
flightPathVectors.AddItem(someVector3);

FlightPathSpline = new(self) class'SplineComponent';

foreach flightPathVectors(pathPointLoc, i) {
    splinePoint.InVal = i;
    splinePoint.OutVal = pathPointLoc;
    splinePoint.InterpMode = CIM_CurveAuto;

    splinePath.Points.AddItem(splinePoint);
}

FlightPathSpline.SplineInfo = splinePath;

FlightPathSpline.UpdateSplineCurviness();
FlightPathSpline.UpdateSplineReparamTable();

Then in the actors tick method i have this for moving it along the spline at a constant speed:

simulated function Tick(float deltaTime)
{
    local float totalSplineLength;
    local float distanceToMove;
    local vector planeLocation;

    // Calculate the total length of the spline
    totalSplineLength = FlightPathSpline.GetSplineLength();

    // Calculate the distance the plane should have moved in this frame
    distanceToMove = Speed * deltaTime;

    // Calculate the new distance after moving this frame
    CurrentFlightPathDistance += distanceToMove;

    // Get the new location of the plane at the updated distance along the spline
    planeLocation = FlightPathSpline.GetLocationAtDistanceAlongSpline(CurrentFlightPathDistance);

    // Update the planes location
    SetLocation(planeLocation);
}

The problem i have is that the actor seems to slow down and speed up at certain points along the spline. Here is a video example of what i mean:

It is usually when moving across the individual points on the spline.

Does anyone know why this is happening?

1 Like

This is someone else posting the same issue (this time in UE4): Unreal Engine - inconsistent actor movement speed along spline - YouTube

1 Like

Good job.
It’s amazing that the night sky is also implemented. :clap::clap::+1:

I think the problem you mentioned is just the nature of Spline Curves.
So I don’t think that’s the problem.

What I do is move my pawns applying acceleration towards the destination point, this being a spline point found with GetLocationAtDistanceAlongSpline(). Reaching them, I find the next destination, until the end.
That is, I don’t place the pawn with a setlocation() directly in GetLocationAtDistanceAlongSpline().

(However, I suspect that GetLocationAtDistanceAlongSpline() is quite slow if you move many pawns at once.)

1 Like

No a bad solution. I’ll give it a shot, thanks.

1 Like

I’ve found a solution that solves this issue. Although it does require one additional call to GetLocationAtDistanceAlongSpline().

It’s not perfect, but is very close (in terms of runtime visuals anyway).

It essentially creates adjustments based on how inaccurate the results from GetLocationAtDistanceAlongSpline() compared to the expected distance travelled. By comparing the expected distance travelled with the location returned from an initial GetLocationAtDistanceAlongSpline() call, I create a multiplier to apply to the distance for a subsequent call.

function Tick(float deltaTime)
{
    local float expectedDistToMove;
    local vector planeLocation;
    local float speedAdjuster;

    // Calculate the distance the plane should have moved in this frame
    expectedDistToMove = Speed * deltaTime;

    planeLocation = FlightPathSpline.GetLocationAtDistanceAlongSpline(CurrentFlightPathDistance + expectedDistToMove);

    //Calculates a multiplier, based on how inaccurate the GetLocationAtDistanceAlongSpline spline curve calc is,  
    //so we can apply it and avoid the slow-downs/speed-ups we get if we only use one GetLocationAtDistanceAlongSpline().
    speedAdjuster = expectedDistToMove / DistBetween(Location, planeLocation);

    // Calculate the new distance after moving this frame.
    CurrentFlightPathDistance += (speedAdjuster * expectedDistToMove);

    // Get the new location of the plane at the updated distance along the spline.
    planeLocation = FlightPathSpline.GetLocationAtDistanceAlongSpline(CurrentFlightPathDistance);

    // Update the planes location.
    SetLocation(planeLocation);
}

My plane now moves at a fixed speed along the spline and still benefits from the smoothing of the curves (rather than moving from point to point).

Hope that helps someone.

1 Like