Unreal Engine Adventure Part II: Navigation Setup
Table of Contents
Unreal Engine AI adventure - This article is part of a series.
Unreal Engine Navigation Entry Level #
Opening #
Goal of this post is to explain how to setup Basic navigation using Unreal Engine 5. To not waste your time here is a things I will cover:
- Adding Navigation to level
- Setting up simple test.
- Adding different types of area class
- Dynamic Navigation with open and close doors
- Adding Navigation links
- Adding custom navigation channels
- Adding Custom Navigation filters
Adding Navigation to Level #
We will be using Third person template for this post.
Adding any navigation to level is quite easy we just need to Add Nav Volume Box.
Then we scale it to determine which part of level should be affected by navigation. For me it looks like this.
If you don’t see green field you should enable view option for navigation we can do it either pressing P
on keyboard or selecting proper option in Show menu
This should fix it. If not check if Nav Volume is overlapping floor and if floor (if you are using custom mesh) have collision.
Now we need to check if our regions works.
Setting up simple AI to test navigation. #
To test our navigation we will create simple AI that will move to direction we will point it to. (To watch it we will use simulate rather then play in editor).
Classes #
To do so we can create simple blueprint actor that will be named for instance BP_TargetPoint
.
This BP will have Actor
as base class and will have just one property. Our property is vector of name VectorTarget
that is public and have ticked Show 3D widget
(If we press on VectorTarget
variable in BP editor in details we will see that check) for clarity. After this we can simply add this point to level by just dragging it in. If done correctly we should have this effect:
Now let setup simple AI.
BP_SimpleAIController
have base AIController
. After creating it we need to put our AI pawn to level, we can simply drag and drop BP_ThirdPersonCharacter
on level and find in details AI Controller Class
and change select our newly created AI controller.
Logic #
We can now focus on logic. We are adding new property in BP_SimpleAIController
TargetPoint
of type BP_TargetPoint
we will setup it with references to our object during begin play of controller.
Setting up can be done like this:
After this let just add simple AI function that will will use to for better changes. Those functions would be:
Start Following
(function should have checkedcall in editor
checkbox in details) We should uncheckStop on Overlap
and setAcceptance Radius
to0.0
to not need to calling this method on every time we have movedTargetPoint
Actor.Stop Following
(function should have checkedcall in editor
checkbox in details) Now we can test our navigation and simple AI. After presing simulate we should selectBP_SimpleAIController
and click onStartMovement
button in it’s details. This should issue movement command of Pawn with TargetPoint as it goal. If we uncheckedStop on Overlap
and setAcceptance Radius
to0.0
we should be able to just moveBP_TargetPoint
actor and AI should follow (it will stop following if we either move our point out of navigation area or we click on stop movement button inBP_SimpleAIController
details)
Different area classes #
Now let scale and move this Nav volume to be on whole level. Adding scale at Z axis will generate navigation mesh on platforms.
Blocking #
We can simply block ability of AI to move in some spaces, easiest way to do it is just not creating navigation volume in that place, but that would be tedious if we are making some level with walls, boxes, trees and so on. So to create small holes in our Navigation mesh we need to add blocking area, by default it is named NavArea_Null
.
We have couple options if we want to add some blocking area, most of them are cutie easy to grasp so I will list them:
- Adding
Nav Modifier volume
that haveArea class
set atNavArea_Null
- Adding any static mesh that have collision and have checked
Can Ever affect navigation
As we can see our AI Pawn will try to find path only on non blocked nav meh (Green colour) and when we move Target point inside blocking area, Pawn will stop moving unable to find proper path (or find closes path on nav mesh depending on settings).
Obstacle #
Obstacle is defining this part of navigation area that should have lower priority then other parts. That mean that AI will only use this area if achieving given area is impossible without it. We can do it by for instance adding Nav Modifier volume
that have Area class
set at `NavArea_Obstacle.
Area that have lower priority have red colour.
This works well if we want to create wall of fire that would take AI health so AI will not go into fire if that is not necessaryWe can see that our AI Pawn can actually walk on Obstacle Are but use this part of Nav mesh only if there is no other way.
Low Height #
This area is a bit problematic as it looks like intraversable area that should be placed when there is insufficient height for AI. Looking at source code I can only conclude that this is designed for AI that needs to have special Nav filter that would make that area traversable.
Dynamic Navigation with open and close door #
In this part we will try to make simple movable door that will affect navigation during game play.
Creating doors. #
I have used `SM_Cube` from default unreal template to create this simple wall and what we will turn into dynamic gate (the one on left, selected, scaled in Z axis not only in Y axis). After this step I want to convert it into bp to add some logic into it. We can easily do this by selecting this object and clicking on this icon in detail In Blueprint we should swap root component from `StaticMeshComponent` into `Scene Component` to do so we can simply add Scene component and drag it and drop on place of Current root component (that is `StaticMeshComponent`). Remember to change relative transform of `StaticMeshComponent` into `0,0,0` vector After this we can add function logic to open and close gate with some interval. Firstly let check when our gate will be open by rotating it to check what is our desire open rotation. As we can see our desire rotation is 90 in Z axis and that gives us rotation vector of `0,0,90`. **Important! Make sure that all rotations other then whole BP are set to 0** while creating example my rotations where 90 for object, -90 for root and 90 for static mesh, after setting **all** of them into 0 it logic worked correctly. I created Custom Event in our newly created bp that have 'Call in Editor' checked in. After playing simulate and pressing button on gate we should have this effect. As we can see navigation area doesn't change, Ai sees it as if that gate is still closed so it will not use faster path. To fix it we have two possible actions: * Make all navigation dynamic (which will impact performance so should be only turn on if we are sure we want to do it). To do so we can simply open `ProjectSettings->Engine->NavigationMesh->Runtime->Runtime Generation` and change from `static` into `Dynamic`. After playing simulation and using button on our BP we should observe that Nav mesh is updated dynamically. * Another, better way to do it is to make only one part of area dynamic. First we need to go to `ProjectSettings->Engine->NavigationMesh->Runtime->Runtime Generation` and change from `static` into `Dynamic Modifiers Only`. Then we will edit our Gate blueprint by unchecking `CanEverAffectNavigation` from static mesh and adding new object as it child that is of class `Box Collision`. Then we need to scale our box to our mesh (I did it by firstly scaling it by X value in front of static mesh and then moving it into static mesh)Note that we need alignment only on X,Y axis as we want to dynamically block area underneath
Next we need to search BoxComponent
properties for Navigation and check DynamicObstacle
as well as un check Use System Default Obstacle Area Class
and select Area Class Override
to NavArea_Null
Last point is to change ProjectSettings->Engine->NavigationMesh->Runtime->Runtime Generation
into Dynamic Modifiers Only
that will make Nav mesh to be generated statically before game and only recalculate it in places that needs it (have Dynamic Obstacle).
This should us same result as above but don’t cost that much performance.
Let see how it works with AI Pawn.
Navigation links #
Navigation link have couple of usage but essentially it connects two points on NavMesh. In algorithm cost of using Navigation should cost close to nav cell traversal. This mean that nav links should be used to create shortcuts for AI. We will gradually customize Nav link to understand what they can provide.
Setting up SimpleNavLink #
There are couple of important settings in object details that maybe important to talk about.
Firstly Let spawn Navigation Link. We can simply press quick add to project
and type NavLinkProxy
.
This should spawn object with one Sprite (pivot of whole Link) and two points that are defining link destinations.
Lets take a look at Details tab and what we try to understand what we can specify there.
It is important to point that currently NavLinkProxy
have two different usages.
SimpleNavLink
- This is always enabled link that gives ability to move over blocked paths, we can have multiple points of this link. It can be used to handle falling of ledge, or passing on blocked navmesh in specified places. Let see how it looks in our project.
We want AI to move to target point using passage (yellow arrows) but due to our cell size and blocking cubes our Pathing algorithm will choose path in red. We can try to solve it making cell size smaller, playing with dynamic obstacle (dynamic obstacle can actually be dynamic passage) but best way to solve it is to use SimpleNavLink
.
We can simple add NavLinkProxy
setup two points and it will work.
SmartNavLink
- This can be either enabled or disabled and is mostly used to create some more complex actions that are taking part in path calculation. This should be understand as example of smart object (AI objects that self defines it’s usage). We can use it to create teleports, Jumping, launch pads. We will touch this topic a bit later.
This is array of pair of points, where we can pick locations of points.
Left
andRight
defines location (relative to owner)Left Project Height
andRight Project Height
are defining height of world form that height it will try to project navlink down.Snap Radius
is defining size of Nav Link activation shape (Big snap Radius)Direction
, we can setup link in only one way.Snap to Cheapest Area
- this nav link snap are will have cheapest value of cells underneath. If weNavArea_Obstacle
andNavArea_Default
both inside are of NavLink point path algorithm will calculate it cost as lowes of both (NavArea_Default
).Area Class
- this determines cost of using link.
Rest of categories like Smart Link
, Broadcast
or Obstacle
will be explained in Setup Smart Link
part.
Dropping from ledge #
To create simple drop from edge navigation link we will use Simple Nav link
. We can simply add object on map and move it on proper place. I have created one NavLinkProxy
actor that have 2 pairs of PointLinks
and both of them have Direction
set to Left To Right
you can observe that in both pairs my left points are up and due to direction setup arrow is pointing only down.
No we can simply test it using our AI and simulation.
Setting up Smart nav link #
This needs Smart Nav Link so we will go over what is smart link and it’s details below. Smart link can only connect two points per Nav Link. The main idea behind it is to have link as a visual representation and internal logic how to handle actor using it. That way we can create teleport that we can easy tweak and if we decide that we rather then teleport have launch pad, change would be way easier. Smart link is smart to put emphasis that this object is carrying logic and thus this should be consider as smart object. Lets take a look at details of Smart nav link:
Smart Link
Enable Area Class
andDisable Area Class
are defining how Link points should be view by AI depending if they are Enabled or not. In this example if our Link isEnabled
AI will see it asNavArea_Default
and in case if Link is disabled AI will see it asNavArea_Null
(blocked) this means that in that case AI will ignore Link in case it is disabled.Link Relative Start
andLinkRelativeEnd
- This are locations of link points whereStart
equalsLeft
andEnd
equalsRight
. This is quite important due toLink Direction
UsingLeft
andRight
rather thenStart
andEnd
.Link Enabled
- defines if link is working or notCopy End Points from Simple Link to Smart Link
buttons - this will copy value of 1st pair of points inSimple Link/Point Links
intoLink Relative Start
andLinkRelativeEnd
. This is important as Advanced 3D display is not dynamic for Smart Points Vectors.Smart Link is Relevant
- It informs if this Nav Link is a smart link.
Proper way of setting it up would be setting pair of Simple Link points up and then pressing Copy End Points from Simple Link to Smart Link
buttons and turning on Smart Link is Relevant
that will create visualisation of smart link points (to update this visualisation you need to recheck Smart Link is Relevant
). Last step would be removing SimpleLink points.
Broadcast
Here we can setup broadcasting state of some nav link. This will send information using specified trace channel and we can implement how receiver should react.
Obstacle
We can decide to create Box Obstacle of given area type in location of Nav Link Pivot (Place where is sprite)
Teleport #
Our first smart nav link will be simple teleport. To create our own logic in NavLink we need to create new BP that is children of NavLinkProxy
. Then we need to simply override Event Receive Smart Link Reached
. Here is a blueprint Event to create teleport between to places.
Let remove all other links and use our new Smart Nav Link. Note that I specially added Disable node to disable AI to returning same Nav Link. Here is a simple demonstration.
Jumping #
To create a jumping we will create new NavLinkPoxy
and overload Event Receive Smart Link Reached
with different logic
Important! There are two important changes firstly we are multiplying Launch Velocity by 1.5, it isn’t perfect but it enable our AI to go over “fence”. Secondly we are not disabling this link. If we disable link before AI traverse it it will trigger path recalculation that will broke our path.
This is how the final project looks:
Custom navigation area classes #
We can define specific navigation area that will be used for specific AI or that will be more preferable. To create new Navigation area we need simply create new blueprint and choose Nav Area
as Parent class.
Inside we can change it’s parameters such as:
Default Cost
- cost of moving using it.
Fixed Area Entering Cost
- cost for entering into Area
Draw Color
- Color of new nav mesh area.
I have set Default cost to 0.1 (to be more preferred then default) with Blue color. To add it into level we can add Nav Modifier Volume
(quick add to project). Now depending on Target location and Where new nav area is we can manipulate where our AI will go. Let compare Movement before and after addition of Nav Modifier Volume
with new cheap area.
Custom navigation filters #
We have created custom Nav area but we still didn’t addressed issue that every costs and movement behaviour is the same for every Ai. Filters address this issue. Let imagine situation where we created custom Area, that is making dmg to all characters, thus AI want to avoid it
And then we decided to create Fire Elemental that not only is not taking damage but it is also making him stronger. In that case our Elemental should prefer to move inside fire. To override default values of we can use Navigation filter.
To showcase this I created copy of our AI pawn and changed a few colors to show that this is Fire loving character. Secondly I have added custom Nav area (I changed color and values of previous custom nav area). Making it costly and red. Then I have created copy of AI controller (Named FireElementalAIController
) (later we will change it’s Navigation filter)
In last part I created new custom navigation filter. To do so we need to create new Blueprint class and select as it’s parent Navigation Query Filter
inside we can specify which area we want to override, by adding new item to Areas array. This is filter for Fire Elemental so I decided to change costs for Fire Area to default value (1.0) and Default value to 10.
Now we need to open our FireElementalAIController
(copy of our BP_SimpleAIController
).
And pick newly created filter from drop down list in details in Default Navigation Filter Class
. And In newly created fire elemental pawn (copy of our AI pawn) we need to select FireElementalAIController
in AIControllerClass
field.
After that I have created Nav Modifier
to show how pathing may change based on filter. This is the result: