Spline GetInputKeyAtDistance return wrong value

When I’m using a splien component, “Get Input Key at Distance Along Spline” returns value from 0.0 to 1.0. This makes no sense.

I have 4 points in spline, the input key range should be from 0.0 to 3.0.
As the screenshot shows, I use the full length of the spline, the input key should be last point’s input key 3.0. But I got 1.0.

I check the C++ code of this function. I don’t understand why there is a TimeMultiplier. Why we need it? And what is the Duration of a spline component?

float USplineComponent::GetInputKeyAtDistanceAlongSpline(float Distance) const
	const int32 NumPoints = SplineCurves.Position.Points.Num();

	if (NumPoints < 2)
		return 0.0f;

	const float TimeMultiplier = Duration / (bClosedLoop ? NumPoints : (NumPoints - 1.0f));
	return SplineCurves.ReparamTable.Eval(Distance, 0.0f) * TimeMultiplier;

As far as I can tell your interpretation is correct; all that extra code is not needed.

I now use a custom variant of the spline class that adds a simplified version of the function.

/** Given a distance along the length of this spline, return the corresponding input key at that point, but this one actually works, unlike the standard one */
UFUNCTION( BlueprintCallable, Category = Spline )
float GetInputKeyAtDistanceAlongSplineActual( float Distance ) const;
float UCustomSplineComponent::GetInputKeyAtDistanceAlongSplineActual( float Distance ) const
    return SplineCurves.ReparamTable.Eval( Distance, 0.0f );

I suppose you could also set the Duration to match the number of segments or something, but that seems unnecessarily complicated.

Hey @EvenZHAnglll. First of all, splines are thought to be used for animating things, that’s why they have a Duration variable. The Duration should be the length of the animation, by default it always goes from 0 to 1. I think you can change the Duration value in the Details panel of your spline. The TimeMultiplier value seems to be used to loop around the spline once you reach the end, that way you can have your animation looping if that is what you want.

You say your spline has 4 points, but that doesn’t mean that the length of your spline is 4, it is still 1, unless you change it manually. That is why you always get 1 when you pass the total length of your spline as a parameter to the function in the first screenshot.

Splines have many methods available for you to ask different position along the spline, you can do it by a getting the closest point in the spline given a world location, maybe you should check to see which method is the best for your needs.

If you need further help please leave more details on what is it that you want to achieve with your spline.

Hope this helps

The duration might still be one, but that’s only relevant for animation, not for spatial curves. The spatial length depends on the path of the curve, and that’s what the ReparamTable helps you look up (the table stores an estimate based on linear sections).

Based on the names of the functions you would expect that GetLocationAtSplineInputKey using the input key from GetInputKeyAtDistanceAlongSpline would be the same as calling GetLocationAtDistanceAlongSpline. It isn’t when there is more than one curve in the spline. That’s the problem.

The current implementation should be named GetTimeAtDistanceAlongSpline, and my suggestion — or one that supports looping — should be used for GetLocationAtDistanceAlongSpline.

That said, it’s been a year since EvenZHAnglll posted. The only reason I resurrected this topic is because I ran into the same problem and wanted to document the solution.

Thank u. I knew the concept of spline. I just confused about the unconsistency of the blueprint functions naming.

Thank u for ur reply. You are right. The question I had at first was that the meaning of “Input Key” is unconsistent in different functions. I even suspect that I have misunderstood about the concept of “input key”.

Here are the facts. The “Input Key” in functions similar to GetXXXXAtSplineInputKey means the index of the spline point. As shown in the example below:

But the “Input Key” as a return value in GetInputKeyAtDistanceAlongSpline is not the same “InputKey” above. It’s range from 0 to 1. This function should be named like RC-1290’s suggestion using another word “Time”, instead of using the word “InputKey”.

Yes this appears to be an incorrectly named function. FindInputKeyClosestToWorldLocation() returns a value from 0..NumSplinePoints, while FindInputKeyAtDistance() returns a value from 0..1.

So to find the correct InputKey when using FindInputKeyAtDistance(), you need to multiply the result by the number of spline points - 1 (for an open spline), and then divide by the Duration value.

Of course it could be I misunderstood what InputKey represents, but that one function returns a different value to another for the same position in the world suggests it’s an error on Epic’s part.

FTW I’ve attached a function that returns the expected whole and fractional version of the InputKey.