Behaviortree MoveTo Node does not finish execution

Hello!

I’ve wanted to create a simple patrol movement between two simple actors with location that point to eachother. I managed to do it earlier, but for some reason it doesn’t work right now. I have the simple path actor set up and the AI character is moving towards it, but once the character overlaps with that simple actor, it will stand on it and the move node won’t finish.

I’ve tracked and debugged the MoveTo node code.
If I understand right “bAlreadyAtGoal” in AAIController::MoveTo function should finish the MoveTo execution, so two cases that can affect it are on the line:

bAlreadyAtGoal = bCanRequestMove && PathFollowingComponent->HasReached(MoveRequest);

bCanRequestMove should be true whenever movement happens, but PathFollowingComponent->HasReached(MoveRequest) checks if I already reached the goal, but seemingly it returns false, because bAlreadyAtGoal is never true and statement gets never called.
if (bAlreadyAtGoal)
	{
		UE_VLOG(this, LogAINavigation, Log, TEXT("MoveTo: already at goal!"));
		ResultData.MoveId = PathFollowingComponent->RequestMoveWithImmediateFinish(EPathFollowingResult::Success);
		ResultData.Code = EPathFollowingRequestResult::AlreadyAtGoal;
	}

UPathFollowingComponent::HasReached function it’s reachmode is EPathFollowingReachMode::OverlapAgentAndGoal.

bool UPathFollowingComponent::HasReached(const FAIMoveRequest& MoveRequest) const
{
	const EPathFollowingReachMode ReachMode = MoveRequest.IsReachTestIncludingAgentRadius() ?
		(MoveRequest.IsReachTestIncludingGoalRadius() ? EPathFollowingReachMode::OverlapAgentAndGoal : EPathFollowingReachMode::OverlapAgent) :
		(MoveRequest.IsReachTestIncludingGoalRadius() ? EPathFollowingReachMode::OverlapGoal : EPathFollowingReachMode::ExactLocation);

	return MoveRequest.IsMoveToActorRequest() ?
		(MoveRequest.GetGoalActor() ? HasReached(*MoveRequest.GetGoalActor(), ReachMode, MoveRequest.GetAcceptanceRadius()) : false) :
		HasReached(MoveRequest.GetGoalLocation(), ReachMode, MoveRequest.GetAcceptanceRadius());
}

In the return statement **MoveRequest.IsMoveToActorRequest()** returns always true. So it always enter this statement:
(MoveRequest.GetGoalActor() ? HasReached(*MoveRequest.GetGoalActor(), ReachMode, MoveRequest.GetAcceptanceRadius()) : false)

And **MoveRequest.GetGoalActor()** never returns nullptr. So it always enters this function:
HasReached(*MoveRequest.GetGoalActor(), ReachMode, MoveRequest.GetAcceptanceRadius())

Next, through HasReached function UPathFollowingComponent::HasReachedInternal is called, which never returns true (which would be neccessary to finish MoveTo execution), although when I debugged whether AI character is close to the goalactor, it doesn't return false. It's a mystery for me.

I have no idea what could cause this strange behavior. If you need more information about that, feel free to ask.

With regards.

Waiting for you response.



The problem is definitely not behaviortree-related as I already had one behaviortree that’s about patroling between two simple actors and when I change the behaviortree and set it up for my character, my character will move to one of those actors, but will stand there without finishing MoveTo node execution.


Also when I add my previously created patroling AI character to that location, it will move nicely between those two actors. So there is nothing wrong with those simple actors that have to be reached when character is patroling. So the problem is related either with new AI character or new AI controller.

The problem is definitely associated somehow with the AI character, as I tried to use different controller (the controller that drives already working patroling AI character, which works) with that character and it still does not work. The problem must be releated to the character.

I solved the problem myself. The problem was still in AI Controller class and was caused by not starting behavior tree through UBehaviorTreeComponent. Instead I started the behaviortree through AIController.

BT_Component->StartTree(*Character->BehaviorTreeAsset);  <--------- the correct function
RunBehaviorTree(Character->BehaviorTreeAsset);

I am still note sure when or where should AAIController::RunBehaviorTree(UBehaviorTree* BTAsset) function ever be called. What’s the purpose of this function?


Waiting for your response.

With regards.

Hi there. Thanks for sharing your findings. I had a similar issue as you and hoped that this post may have the solution but alas it was a different error that caused my particular issue. But luckily I figured out the cause for my issue as well.

In case anyone else has a similar issue of the AI move not completing its move (i.e. OnMoveCompleted() never fires), in my case I had made the mistake of overriding the OnPathFinished() function in UPathFollowingComponent, but without calling Super::OnPathFinished() first. So OnMoveCompleted() never ran.

1 Like