Training PhysX Characters to navigate narrow ledges!
In video I trained my Physics-simulating AI units to stay on narrow ledges!
My final algorithm to do what you see in video ended up being only about 3 lines of code!
I show before and after video segments so you see what I achieved!
I did all of with a C++ custom UE4 path following component, using the UE4 navigation system.
**My Goals**
**Goal 1: **To enable PhysX-simulating characters to use UE4 Navigation system
**Goal 2: **To enable such PhysX-simulating characters to not fall off of every ledge as they try to path along narrow ledges to get to the player, without cheating / using Editor helpers or making it look artificial/clunky! The final movement still needs to look natural and PhysX-y !
**All goals achieved by end of video!**
https://youtube.com/d7mAhStMABo
Enjoy the video!
PS: Yes I did say **PhysX-y**! You know what I am talking about!
In video you get to watch as I construct a section of level using my in-game level editor tools!
Then my physX-simulating ball characters are able to path over the ledges using the ledge-path AI I developed and demo in a prior video!
**In-Game Editor Tools**
Again video is a fun demonstration of my in-game editor tools that are used to build levels while the UE4 Editor is closed!
Watch my AI units easily path over and through these **runtime user-generated** sections of level!
UE4 Nav Mesh Rebuild At Runtime
video shows off how good UE4 rebuild at runtime is, as you watch the AI find my player unit amongst dynamically generated pieces of level that you watch me build during the video!
Awesome work! I can’t tell you enough how many times your posts and answers scattered throughout the Unreal World, have helped steer me in the right direction on multiple occasions.
I have been trying to do a similar path finding jump as your videos above, but am getting stuck on one part, On your #140 comment , the video shows some dynamic path finding and jumps being made by the AI to get to the player. I have been looking at the Recast Nav mesh and am able to find the nearest poly and the get all polys methods you posted but the find nearest seems to only return a poly on the same area and the find all polys returns everything it seems. Is there a find nearest poly between two areas? I cant seem to find a query function that finds where the AI should start its path at, given the player being a couple jumps away. In your example video, I see you have two poly areas being highlighted the yellow ones that signal where the AI should move to and the green ones that signal where to jump to. Is it possible to shed some light on how to get those polys? I don’t care about sharing code as much as just an explanation of the idea you used, as I still want to learn for myself, just cant seem to figure out a way to accomplish that part.
That was actually the most complex part, I did a bunch of geometric tests to identify the proper points using FBox and line tests.
After obtaining the FBox that represents each poly, I then did a bunch of tests to see which one was the best for the unit to use
Here’s the function I created in my custom PathFollowingComponent to initiate my geometric tests:
//Verts
bool NavPoly_GetVerts(const NavNodeRef& PolyID, TArray<FVector>& OutVerts);
//Bounds
FBox NavPoly_GetBounds(const NavNodeRef& PolyID);
//Choose Which Nav Data To Use
FORCEINLINE const ANavigationData* JoyGetNavData() const
{
const FNavAgentProperties& AgentProperties = MovementComp->GetNavAgentPropertiesRef() ;
const ANavigationData* NavData = GetNavDataForProps(AgentProperties) ;
if (NavData == NULL)
{
NavData = GetMainNavData();
}
return NavData;
}
//~~~
bool UJoyPathFollowCompHighest::NavPoly_GetVerts(const NavNodeRef& PolyID, TArray<FVector>& OutVerts)
{
//Get Nav Data
const ANavigationData* NavData = JoyGetNavData();
const ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(NavData);
if(!NavMesh)
{
return false;
}
return NavMesh->GetPolyVerts(PolyID,OutVerts);
}
//Get Box of individual poly from verts
FBox UJoyPathFollowCompHighest::NavPoly_GetBounds(const NavNodeRef& PolyID)
{
TArray<FVector> Verts;
NavPoly_GetVerts(PolyID,Verts);
FBox Bounds(0);
for(const FVector& Each : Verts)
{
Bounds+=Verts;
}
return Bounds;
}
**Geometric Analysis Using FBox**
I had to do all the geometric analysis myself!
I recommend you check out all the convenience functions in:
**UnrealMathUtility.h**
and
**Box.h**
These are the basic tools you can use to do the analysis yourself to find the best spot!
Essential Function
I especially recommend checking out a fast trace you can do using a Line Box intersection:
UnrealMathUtility.h
/** Determines whether a line intersects a box. */
static bool **LineBoxIntersection**( const FBox& Box, const FVector& Start, const FVector& End, const FVector& Direction );
/** Determines whether a line intersects a box. overload avoids the need to do the reciprocal every time. */
static bool** LineBoxIntersection**( const FBox& Box, const FVector& Start, const FVector& End, const FVector& Direction, const FVector& OneOverDirection );
/* Swept-Box vs Box test */
static CORE_API bool **LineExtentBoxIntersection**(const FBox& inBox, const FVector& Start, const FVector& End, const FVector& Extent, FVector& HitLocation, FVector& HitNormal, float& HitTime);
**Multi-Threading**
I multi-threaded my final solution to result in best performance.
Good Luck!
I look forward to hearing about your chosen implementation!
I’ve just posted a C++ wiki on implementing an AI Dodge mechanic!
In just a few lines of code I show you how you can tell an AI unit to dodge left or right, and how far, and also ensure the UE4 Navigation System will find the calculated dodge point using Nav Mesh Projection!
Hi
Just want to know, you remake navigation system or add extra validation on unreal path finding system?
is can be implementable to big landscape like open world game? because you got all polys…
I am using UE4 navigation system for my more recent jump pathing videos, I’ve also created my own navigation systems / nav mesh / AI path following, from scratch!
Epic has a nice way to stream in nav meshes, and also nav meshes can be separated, so that the lookup of all polys is local to the units nearest nav mesh, meaning I am not looking up all polys in the entire open world