Flying with Character Movement Components + Move to Location?

Hey there. I am trying to create a basic flying AI, but I’m unsure of how to get it working properly. I know how to get a ground AI working, but when I switch it’s movement type to Flying, Move To Location stops working - he just sits still. I know I could force the functionality that I want using blueprints but I wanted to get it working using the movement component so I can use the built in Move to Location and nav mesh.

Is that even possible? I’m assuming it is because there’s a flying section on the movement component. I just can’t get it working.

Thanks for any help :slight_smile:

I looked into this myself as I wanted to use the FlyingMovementComponent to make a space ship fly, but the moveTo AI node didn’t seem to do anything.

If you want a space-ship
If you’re planning to use the AI moveTo nodes for space flight and completely disregard the nevmesh system, then you simply need to disable the “use Pathfinding” option on the moveTo node.

If you want to have a Pawn floating on the NavMesh
If you want a hovering droid that follows you around on the navmesh at a fixed height, then you need several things:

  • The Root component should be a collision component (eg. capsule collision)
  • The object should be placed so that the Root component intersects (is on) the navmesh.

Note that your root component can be non-colliding and used purely for the navmesh. You can have a second component for actual collision which floats above the ground (other issues with secondary collision components may apply, ymmv).

If the navmesh implementation can’t resolve a path from A (root collision) to B (approx destination), then it’ll return an Error result in the move function.
The navsys expects your Pawn to be on the navmesh, so if the floating pawn is not on the navmesh, some checks always fail, and the moveTo function is basically aborted.

Specifically the moveTo action will call FindPathForMoveRequest, which will encounter an error response from the NavSys:

FPathFindingResult PathResult = NavSys->FindPathSync(Query);
if (PathResult.Result != ENavigationQueryResult::Error)
    // ...

That failure is caused by InitPathfinding failing in the RecastNavMesh, which is unable to find a polygon for the start/end position of the move across the navmesh.

const bool bCanSearch = InitPathfinding(StartLoc, EndLoc, NavQuery, QueryFilter, RecastStartPos, StartPolyID, RecastEndPos, EndPolyID);

Interestingly the option “project destination to navigation” allows you to make a moveTo request to an arbitrary location, and the location will be projected onto the navmesh before the destination is calculated. This allows destinations to be in odd positions not on the nav-mesh and still resolve happily to the navmesh.
Similarly the “Allow partial path” option lets you ask for a destination which isn’t on the navmesh, and the navsys will still resolve a destination as-close-as-possible rather than failing.

What isn’t accounted for by navsys, as far as I can tell, is the ability to project the source position onto the nevmesh, so that you can use a floating pawn which might not necessarily start on the navmesh.

There’s lot of reasons why doing that could lead to weird results (eg. if the pawn is two miles up and needs to fly into a tunnel, how does the navsys know where it’s safe for the Pawn to “land” on the navmesh before entering the tunnel? What if there’s other obstacles on the way down?), so generally if you want to use the navmesh for the Floating pawn, it’s best to try and keep that Pawn on the navmesh at all times.

I’d personally recommend applying a “light” gravity to the Pawn so that it “re-settles” onto the navmesh should it become detached and truly floating in the air.
Otherwise if you do want it to depart the navmesh for periods all together (true flight in 3d space), you might want to have “landing” areas (volumes, actors) where the Pawn can locate a safe position to land back on the navmesh and resume its floating behaviour.