Incorporating a custom movement component into UE4's AI/pathfinding system

I spent the last few hours studying the source code and searching the internet for whatever information I can find on this. There’s virtually no documentation and it would seem to me the only way to understand what to do is to reverse engineer the engine’s code, which takes time I don’t have.

I have a custom movement component that implements the functionality I need. It is rather isolated from the rest of the engine since it defines and deals with problem such as walkable slopes, jumping, flying state and other such common problems by itself. Unfortunately, I’m not sure it will work with the AI system as it is, because UE4’s AI system seems hopelessly tied to the default character movement component.

From the source code I noticed some interesting classes, most notably the UPathFollowingComponent and the UNavMovementComponent, but I haven’t quite figured out what to do with them yet. It would seem UPathFollowingComponent has functions that would allow me to retrieve a set of waypoints I could then use to move my character to a destination(although they seem to be mostly deprecated), while UNavMovementComponent seems to expect me to update some inherited values in order to be used by the AI and navigation system.

I haven’t tried anything yet, so maybe my movement component will automagically work with the AI system, but I doubt it. This is problematic because a huge chunk of the game is already built on top of my custom movement logic. AI is all that’s left for me to implement, and I really don’t want to rewrite the entire navigation system for this.

I’d appreciate if anyone could tell me how to get the existing AI system to function with a custom movement component, or at least point me in the right direction.

You may want to look at the code of UT which (if my memory is right) has its own custom movement routines. Useful files might include…ovementTypes.h among others. This should give a good idea on integrating the custom movement with the Engine.

Just remember that the game code is based on old engine and you may want to keep the deprecated functions in check.

Let me know if you want more specific help!

Thank you. From the source it would seem their custom movement component(UUTCharacterMovement) inherits from UCharacterMovementComponent, which means they skip the problem. My movement component inherits directly from UPawnMovementComponent, so I’m assuming it can’t be used with the AI as it is since UE4’s AI seems to require a UCharacterMovementComponent. It could be bots use a different movement component, but I haven’t found anything, so I’m assuming they share the same movement component as the player.

From the engine’s source I do know that UPawnMovementComponent inherits from UNavMovementComponent, and if the description of that class is correct this would imply UPawnMovementComponent has the functionality to work with pathfinding. All I really need is the MoveTo() function to work with it, and to do that I suspect I need the nav movement component’s inherited flags to reflect my owns calculations so pathfinding knows what to do(tell whether it’s moving, whether it’s flying, on the ground, etc). I’m still looking into which flags to update though, or what functions to implement.

I haven’t tried anything yet, so maybe it will just work. I’ll do that now and check whether it works or not. Velocity is updated properly and I have all the common states working, so it should at least react in some way.

You need to at least inherit from UNavMovementComponent, as that provides the interface for the engines Navigation System.

virtual void RequestPathMove(const FVector& MoveVelocity) override;
virtual void RequestDirectMove(const FVector& MoveVelocity, bool bForceMaxSpeed) override;

The pathfinding will call these functions in your UNavMovementComponent - it’s up to you what you do with the requested data then. You can write your own PathFollowingComponent if you want to pass different data along.

The ‘Velocity’ that is passed in is just the current difference between the agent location and the next path point / target.

Thank you TheJamsh, that is exactly what I needed! I just implemented a test and it worked perfectly with a simple decision tree. The character properly avoids obstacles and pursues the player character using my custom movement logic. That is great!

I saw a lot of people having trouble with this on google, which is part of the reason I was worried. I’ll leave some notes here to help others who may happen upon this thread.

Looking at the implementation for those two functions in the UCharacterMovementComponent greatly helps you to understand how the default character movement component deals with pathfinding. I took a look at the header file for UNavMovementComponent and also saw three other interesting fuctions, which are all overridden in the UCharacterMovementComponent class. Those are:

virtual bool CanStartPathFollowing() const override;
virtual bool CanStopPathFollowing() const override;
virtual float GetPathFollowingBrakingDistance(float MaxSpeed) const override;

The first two are self-descriptive. They return bool and let the pathfinding system know whether the character can start following or stop following some path, respectively. This sounds important for scripted situations, or when a character is say, falling or staggered from a heavy attack and can’t follow a path.

GetPathFollowingBrakingDistance() seems most useful for high speed pawns and characters that require smooth braking and turning, such as space ships, cars and such.

Anyway, all I did was use the given velocity to calculate the movement for my AI character using my own movement component’s functions and a decision tree with a MoveTo node, and it worked.

Thanks again!