Character stopping before moving to next waypoint

Hi There,

I followed this [AI tutorial series][1] to create a target point based path for my AI character. Everything is working as expected, but there is a small delay with my character when it moves to a new target point. It looks like the character stops and rotates and then continues to the next target point.

Is there a way to make it so that the character does not stop when rotating/going to next target point?

blueprints:

Character blue print:

Behavior tree

Target point/way point.

Hi ! Have you find a solution ? I have the same question :slight_smile:

I have the same question too! Any solutions?

Hey Buddy! I found the solution to this. The character stops on each waypoint because it takes time for the moveto task to finish execute and then set the next waypoint on the btt and then continue. This simply is too slow. The update of where the character will move to next must be recalculated at frame speed so the change becomes seemless. This means it must be handled in the tick task.

The approach I took was making a custom task called patrol, which will check each frame if the character has reached the next waypoint and if so, (without aborting), setting and calling moveto to the next waypoint after that.

Take a look at the btt picture and the code. It will make it easier to understand :slight_smile:

void UBTT_Patrol::TickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)
{
Super::TickTask(OwnerComp, NodeMemory, DeltaSeconds);

AWaypoint* nextWaypoint = character->GetNextWaypoint();
currentWP = nextWaypoint;

// If there is next waypoint then try moving to it
if (currentWP != nullptr)
{
	FVector currentWPLocation = currentWP->GetActorLocation();				FVector characterLocation = character->GetActorLocation();				currentWPLocation.Z = characterLocation.Z;	// to avoid problems 		with WP and character height difference

	// If character already arrived to target
	if (currentWPLocation.Equals(characterLocation, 60.0f))
	{
		bMoving = false;

		// Check if target changed
		if (currentWP != nextWaypoint)
		{
			currentWP = nextWaypoint;
	else
	{
		if (bMoving)
		{
			if (currentWP == nextWaypoint)
			{
				bMoving = false;
			}
			else
			{
				// If target changed try moving to it
				currentWP = nextWaypoint;
				ownerController->MoveToActor(currentWP, AcceptableRadius, bStopOnOverlap);
			}
		}
		else
		{
			// If not moving move to the waypoint
			ownerController->MoveToActor(currentWP, AcceptableRadius, bStopOnOverlap);
			bMoving = true;
		}
	}
}

Hey buddy check out my answer for this if youre still stuck!

(LOOK AT MY COMMENT ABOVE FOR PROPPER CODE FORMATTING!)

Hey Buddy! I found the solution to this. The character stops on each waypoint because it takes time for the moveto task to finish execute and then set the next waypoint on the btt and then continue. This simply is too slow. The update of where the character will move to next must be recalculated at frame speed so the change becomes seemless. This means it must be handled in the tick task.

The approach I took was making a custom task called patrol, which will check each frame if the character has reached the next waypoint and if so, (without aborting), setting and calling moveto to the next waypoint after that.
Take a look at the btt picture and the code. It will make it easier to understand :slight_smile:

void UBTT_Patrol::TickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) { Super::TickTask(OwnerComp, NodeMemory, DeltaSeconds);

AWaypoint* nextWaypoint = character->GetNextWaypoint();
currentWP = nextWaypoint;
 
// If there is next waypoint then try moving to it
if (currentWP != nullptr)
{
FVector currentWPLocation = currentWP->GetActorLocation(); FVector characterLocation = character->GetActorLocation(); currentWPLocation.Z = characterLocation.Z; // to avoid problems with WP and character height difference
 
// If character already arrived to target
if (currentWPLocation.Equals(characterLocation, 60.0f))
{
bMoving = false;
 
// Check if target changed
if (currentWP != nextWaypoint)
{
currentWP = nextWaypoint;
else
{
if (bMoving)
{
if (currentWP == nextWaypoint)
{
bMoving = false;
}
else
{
// If target changed try moving to it
currentWP = nextWaypoint;
ownerController->MoveToActor(currentWP, AcceptableRadius, bStopOnOverlap);
}
}
else
{
// If not moving move to the waypoint
ownerController->MoveToActor(currentWP, AcceptableRadius, bStopOnOverlap);
bMoving = true;
}
}
}

It is very easy, if you change the way of thinking:

Just spawn an invisible actor,
and let your AI to chase it all the time!
(By clicking the ‘use continous goal tracking’ optinal on)

And when you change the waypoint,
just move the invisible actor there,
no need to call ‘move to’ function again,
therefore, the character will not stop.

1 Like