C++/Ai - root motion based controller

I’m trying to implement root motion-based controller that would work with AI decision trees, specifically with decision tree’s “MoveTo” command. The game is supposed to be single player with no network replication.

Now, to make this work all I need is some point in code where controller decided in which direction it wants to go and but haven’t moved in that direction yet. I haven’t located that portion yet.

The problem here is that the whole system is overloaded with stuff created with assumption that the character is not using root motion for movement, and most of the methods aren’t marked as const, so they pretty much expected to change object’s internal state. Basically, MoveTo() action pretty much calls character controller’s “request direct move” which sets “RequestedVelocity” field in movement controller, BUT from that point code adopts the way of spaghetti and becomes convoluted (it doesn’t help that CharacterController.cpp has 200+ kilobytes of code in one file or it does some fun things like passing parameters through member variables instead of function argument).

Has anyone done ai-supported root motion movement in the past? I am starting to think it might be the best idea to drop ACharacter base (and its movement components) entirely and reimplement the whole thing based on APawn class, but that would waste quite a bit of time. Or would it be a better idea to make decision tree drive the character movement? I’d need custom node with pathing support for that.

Looking for ideas/advice here.

I figured it out.


For motion control, you need to to create subclass of UPathFollowingComponent and override

virtual void OnPathFinished(EPathFollowingResult::Type Result) override;
virtual void FollowPathSegment(float deltaTime) override;

OnPathFinished is called when movement stops, and FollowPathSegment is called when application follows some segment.

Also, rotation is handled within

 virtual void AAIController::UpdateControlRotation(float deltaTime, bool updatePawn = false) override;

So, in case of root motion, it’ll be necessary to subclass this one too.

Basically, you need to set motion control vairables within FollowPathSegment, zero them when OnPathfinished is called and handle rotation in UpdateControlRotation. Direction in which Ai wants to look is available via AAIController::GetFocalPoint().