Download

UE4 Pathfinding...basic AI

Hi, I’m new here. I’m fairly familiar with A* pathfinding system using a GridMap (Unity) and modifying existing systems to make them work how I wish. However, I’ve never worked with Unreals NavMesh system.

BUT I could use a slight nudge on how to get started with UE4’s NavMesh to path AI’s around randomly depending on behavior. Also a noob to Visual Programming (BP) but I shouldn’t need to dive too deep into that immediately to get some simple AI working. I couldn’t really find any tutorials or documentation on how to set up a basic AI Agent that paths. When I tried to view the NavMesh example, the BP_Pawns don’t have any Graphs attached to them (that I can see…)

I want to get a capsule walking around a level to random locations. Upon reaching his destination (or if he’s unable to reach it) he should find a new valid target position… What are are the basic steps for this?
Can you guys point me towards documentation or list out the commonly used classes for Pathfinding?

Thanks in advance!

To come later: Getting Agents to communicate between each other along with distance checking to determine their behavior in the most efficient manner…

Me too interested to a tutorial about navmesh usage.

It would seem like “Pawn” or “Character” blueprinting is what I am looking for :smiley: … I’ll start with this when I get home and mess around with some of the classes.

If you are interested in UE4’s AI system, you may find this thread helpful: Behavior Tree Tutorial - Community Content, Tools and Tutorials - Unreal Engine Forums

Random wandering can be achieved in couple of ways, depending on which systems do you want to use.

Best (and most complex) approach is preparing behavior tree - although you have to enable them in editor preferences (menu Edit>Editor Preferences, Experimental section). You may want to check tutorial thread mentioned above, or just follow those steps:

  1. Create new blackboard asset (new Data Asset -> Blackboard), to store destination point: single key with KeyType set to BlackboardKeyType_Vector
  2. Create new behavior tree task for picking random location. This can be done either in blueprint or c++ code:
  • blueprint = new blueprint asset (new Blueprint, parent class: BTTask_BlueprintBase), important: add new variable with type BlackboardKeySelector and make it public (click closed eye next to variable name, opened = public)

aa39d7d04693f5e4b4875618d272010083a02ccd.jpeg

  • c++ = new class derived from UBTTask_BlackboardBase, implement your own ExecuteTask() function


EBTNodeResult::Type UBTTask_FindLocation::ExecuteTask(class UBehaviorTreeComponent* OwnerComp, uint8* NodeMemory)
{
	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(OwnerComp);
	AAIController* MyAI = Cast<AAIController>(OwnerComp->GetOwner());
	if (NavSys && MyAI && MyAI->GetPawn())
	{
		const float SearchRadius = 1000.0f;
		FNavLocation RandomPt;
		
		const bool bFound = NavSys->GetRandomPointInRadius(MyAI->GetPawn()->GetActorLocation(), SearchRadius, RandomPt);
		if (bFound)
		{
			OwnerComp->GetBlackboardComponent()->SetValueAsVector(GetSelectedBlackboardKey(), RandomPt.Location);
			return EBTNodeResult::Succeeded;
		}	
	}

	return EBTNodeResult::Failed;
}

  1. Create new behavior tree (new Misc>BehaviorTree), set your blackboard in root’s properties. You can start with having just a sequence composite with two nodes: Find Spot (task from step 2) and MoveTo, both accessing the same key in blackboard.
    6ead36e62f530c74fd48fe7c520cf2afd70340e5.jpeg
  2. Spawn new AI and make it run your behavior tree. Easiest way is running SpawnAI from level’s blueprint.

As I said, this is most complex way, but gives you best starting point for further modifications. Easy setup for blueprints:

  1. call MoveToLocation/MoveToActor function on AIController
  2. bind ReceiveMoveCompleted event in AIController, use it to detect reaching goal
  3. call GetRandomPoint/GetRandomPointInRadius functions (leave NavData and FilterClass empty) to pick random points on navmesh

Even easier setup for blueprints:

  1. Use “AI MoveTo” function, it should handle finish events for you
  2. call GetRandomPoint/GetRandomPointInRadius functions (leave NavData and FilterClass empty) to pick random points on navmesh

And finally, c++ version:

  1. call MoveToLocation/MoveToActor on AIController
  2. override OnMoveCompleted in AIController to detect reaching goal
  3. accessing NavigationSystem for random points was shown above

While I’m on it, let’s talk about how to influence path finding. You can define different navigation areas, with different travel or entry costs - either in blueprints or c++. Just create new blueprint/class inheriting from NavArea. I strongly suggest to keep travel cost (DefaultCost property) greater or equal to 1. Areas are usually applied by NavModifierVolume or StaticMeshes configured to be dynamic obstacles (check NavCollision property of static mesh for details).

Additionally, you may want to check two more actors: ANavLinkProxy (e.g. jump down links) and ANavigationTestingActor (path finding debug tool, including step by step display).

Hope it helps!

Awesome thanks…behavior trees are exactly what I was looking for.

I figured out how to get a Pawn wandering around fairly easily using the exact method here last night. It was fairly simple to get him to continue wandering by connecting two AIMoveTo functions together. Unfortunately it doesn’t handle turn rate and the Pawn just kind of instantly turn towards target.

I’ll dive into Behavior trees when I get home. Excited.

Instant rotation is probably a bug. Try setting bUseControllerDesiredRotation flag in pawn’s blueprint (c++ = in movement component, CharacterMovement property) to enable use of RotationRate and modify AAIController::Tick


void AAIController::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	UpdateControlRotation(DeltaTime**, false**);
}

It should get rid of forcing pawn’s rotation in every frame and give movement component chance to interpolate.

I know this is probably a dumb question…but how do you access/set other Keys in BlackBoard?

I’m trying to set different AI States which will determine their behavior. Basically…how do you determine which Key you are setting when your BlackBoard contains multiple keys?

If you’re writing C++ code:

You can fetch a uint8 Blackboard KeyID by using an FName that matches the key in the blackboard:


uint8 BlackboardKeyID_Enemy = BlackboardAsset->GetKeyID(EnemyKeyName);

Then you can set values using the appropriate function for the type of key, such as:


Blackboard->SetValueAsObject(BlackboardKeyID_Enemy,  EnemyPawn);

(Also, SetValueAsEnum, SetValuesAsClass, SetValueAsVector, SetValueAsName, SetValueAsInt, SetValueAsFloat, SetValueAsBool, etc. See BlackboardComponent.h for the functions). There are corresponding GetValueAs… functions there as well.

If you’re using blueprints:
The functions above (SetValueAs… and GetValueAs…) are all also exposed as nodes in blueprints which can be called from within Behavior Tree blueprint node objects (decorators, tasks, services).

In the blueprint, you can use a variable of type BlackboardKeySelector and set it as Editable to expose the selection to the details view from within the behavior tree itself. That will let you pick a valid entry from the blackboard you are using within the behavior tree (from a dropdown list). Pass that variable into the “Key” input on the Set/Get node.

Just a heads up Daniel,

Can you make the documentation you’re writing up, idiot friendly :D? … What I mean by that is explaining what those things mean, (in your quote above). To a code literate person it’s black and white, but to a code ignoramus it’s gobbledygook :wink:
That’s why I had trouble deciphering mike_purvis’s post on Behaviour trees, which was not his fault, but the language between coders is like Japanese to me :cool:

A dummy’s guide to AI and behaviour trees would be fantastic :slight_smile:

Yes, the docs I am writing will absolutely be explaining all of those terms in detail and are aimed at getting non-programmers up to speed on how behavior trees work (with notes for programmers as well, but easily skipped by non-programmers).

The only reason I used those terms casually here was that they are shown in the UI, and I was writing this response rather quickly.

Perhaps I’ll post about the different types of nodes soon as I’m just about to go over my notes on node types and make them readable. Then I can take feedback on my explanations into account for the official docs. Which of course implies using all of the common forum posters here as my guinea pigs on how clear my explanations are. :p. I’ve been trying to perform my doc-testing on some folks at Epic first to avoid sewing confusion here. :stuck_out_tongue:

Here’s another thread if you could take a look :D… Behavior Tree C++ related.

Why the bot is not moving?

d85ee49070f9dd6c2470f8b3767b53ef7fd886ef.jpeg


// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#include "Nex.h"
#include "BTTask_MyMove.h"


UBTTask_MyMove::UBTTask_MyMove(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{

}

EBTNodeResult::Type UBTTask_MyMove::ExecuteTask(UBehaviorTreeComponent* OwnerComp, uint8* NodeMemory) const
{
	UBehaviorTreeComponent* MyComp = OwnerComp;
	ANexAIController* MyController = MyComp ? Cast<ANexAIController>(MyComp->GetOwner()) : NULL;
	if (MyController == NULL)
	{
		return EBTNodeResult::Failed;
	}
	else
	{

		// GetSomeLocation is just made up here, it's just an example
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("Key"));
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::FromInt(BlackboardKey.SelectedKeyID));
		FVector Destination = MyComp->GetBlackboardComponent()->GetValueAsVector(BlackboardKey.SelectedKeyID);
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::FromInt(Destination.X));
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::FromInt(Destination.Y));
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::FromInt(Destination.Z));
		// Make a move
		MyController->MoveToLocation(Destination, 60.0f);
		return EBTNodeResult::Succeeded;

	}

	return EBTNodeResult::Failed;
}

Oh man, I can’t wait :slight_smile:
Thanks for replying.

Regards,
Dave

To fix this, go into the movement component of the character and turn on “Orient Rotation to Movement”, then go into the Defaults of the character and turn off “Use Controller Rotation Yaw”. Let me know if that helps.

Hi guys!

Any ETA when we can see the first draft of the documentation for this? Really looking forward to that day :slight_smile:

Are you asking about documentation for our navigation support, or documentation for Behavior Trees? I can’t give an exact ETA for either, but Behavior Tree documentation is coming quite soon now. (Sorry folks, I know I said that before… some unexpected other priorities and a bit of vacation time both bumped it back. But it is coming soon finally. I’ll give a more detailed ETA than “soon” by next week.)

We’re also generally working as hard as we can to get Behavior Trees to a point where we can officially move them out of “Experimental” as soon as possible! That work will include improvements to some other systems as well, so we’ll have information coming on those soon too!

I recall reading somewhere (a post in which I can no longer find, so I could be completely out of my mind…) that behavior trees would potentially be subject to a massive overhaul, or be completely removed in favor of a different system. Is this no longer the case, if it ever were?

Well, part of the point of the “Experimental” section generally is that systems in that section are more prone to large changes than systems that are officially supported.

However, in the case of Behavior Trees, they are definitely not being removed! We hope to have the system ready to move out of the “experimental” section within the next few major releases (the sooner, the better). There may be significant changes in the pipe, but at this point it’s likely we’ll keep backwards compatibility throughout the process. At the very least I’m sure we’ll have a process for any conversion steps required.

In addition to various licensees using it, we’re using Behavior Trees on Fortnite (among other projects), so it’s pretty critical that we not break the system as we move forward with it!

Sorry. Should have been more clear :slight_smile: We are really hoping you guys release some proper documentation and hopefully some official (Zak Parrish) tutorials for Behavior Trees. Right now there are a couple of semi-advanced ones out there, but they don`t explain everything as well as we would like. Zak really does a fantastic job explaining all the minor details, in a funny and very informative way, so yeah… crossing my fingers for some more tutorials from him soon :slight_smile: