Velocity or InputVector in PawnMovementComponent?

I am trying to write a PhysX based movement component based on UPawnMovementComponent. The physics parts is working nicely. To follow an AI path i have found two different ways of getting the movement information:

  1. bUseAccelerationForPaths=true gives the movement information in the InputVector read by GetPendingInputVector()
  2. bUseAccelerationForPaths=false gives the movement information in the Velocity variable.

The names in those input vectors seams to be misleading:

  1. InputVector (bUseAccelerationForPaths=true) gives a suggested speed vector (not acceleration).
  2. Velocity (bUseAccelerationForPaths=true) gives a vector that indicates the distance to the next segment in the path
    (I can post some time-series diagram of this if someone is interested).

However, both the Velocity vector and the InputVector cases gives me a zero-vector when approaching any segment on the path (not just the final segment). This makes my Pawn break and stop at every segment on the path, before continuing to the next segment.

Is there any way to tell if i am heading towards the last segment, so i can avoid breaking at the other segments?
I might also doing something completely wrong, but I have been struggling with this for days so please help…

Solution found!

One good thing about UE4 is that the source is available!
I found this code for the bUseAccelerationForPaths=true:



CurrentMoveInput = (CurrentTarget - CurrentLocation).GetSafeNormal();

if (MoveSegmentStartIndex >= DecelerationSegmentIndex)
{
	const FVector PathEnd = Path->GetEndLocation();
	const float DistToEndSq = FVector::DistSquared(CurrentLocation, PathEnd);
	const bool bShouldDecelerate = DistToEndSq < FMath::Square(CachedBrakingDistance);
	if (bShouldDecelerate)
	{
		bIsDecelerating = true;

		const float SpeedPct = FMath::Clamp(FMath::Sqrt(DistToEndSq) / CachedBrakingDistance, 0.0f, 1.0f);
		CurrentMoveInput *= SpeedPct;
	}
}
PostProcessMove.ExecuteIfBound(this, CurrentMoveInput);
MovementComp->RequestPathMove(CurrentMoveInput);


The direction of the CurrentMoveInput vector indicates the direction to the target and the size of the vector will be 1 until its time to break, then it starts decreasing and will be 0 at the end position.
Note: If you use a large breaking distance and the end-point is i.e. on the other side of a wall that the droid has to go around there will be a decrease in speed (the input vector will be less than 1) when path passes close to the end-point.
The default implementation of RequestPathMove in the PawnMovementComponent will add the CurrentMoveInput into the InputVector
(This is not acceleration this is speed! If it would have been acceleration the value should have been positive at the start, 0 at straight line following and negative at the end of the path for breaking).

This is the code for bUseAccelerationForPaths=false:


		
FVector MoveVelocity = (CurrentTarget - CurrentLocation) / DeltaTime;

const int32 LastSegmentStartIndex = Path->GetPathPoints().Num() - 2;
const bool bNotFollowingLastSegment = (MoveSegmentStartIndex < LastSegmentStartIndex);

PostProcessMove.ExecuteIfBound(this, MoveVelocity);
MovementComp->RequestDirectMove(MoveVelocity, bNotFollowingLastSegment);


The default implementation will transfer the MoveVelocity to the Velocity variable of the movement component.
So by overriding the RequestDirectMove in the movement component you can apply breaking only at the end of the last segment by looking at the bNotFollowingLastSegment. (The default implementation ignores this parameter)
Note: The bNotFollowingLastSegment is named bForceMaxSpeed in the NavMovementComponent which kind of confused me…

(The Velocity will be the velocity needed to bring the pawn to the segment end in exactly one tick(!) or the distance to the segment end divided by the tick-time… so i would say it’s more or less distance divided (or multiplied if you like) by a constant, not velocity!)

To sum this up: The function is there (beside the bug for acceleration in combination with large breaking distances), but the names are confusing and the documentation poor…
Hopefully this helps anyone though…

Thank you for sharing your research @Kartom!

I agree, UE4 Source Code access = Yaay :slight_smile:

:slight_smile:

Rama