Pathfinding in moving ship/NavMesh

How to have AI pawns navigate a moving ship, vehicle, platform, whatever, i.e. where the NavMesh would continuously change?

This has been asked many times before, as far back as 2014, none with proper solution:

Is there still, in UE5, no officially implemented solution to this somewhat basic problem?

The only published workaround i’ve found is as described by the “Sea of Thieves” developers for their “Skeleton ships”, where they seem to have a stationary clone of the ship mesh with a baked navmesh, then use it for pathfinding queries, somehow transforming the result, see:

Any further knowledge on how it’s done/integrated?

Could it also work for a NavMesh that’s updated dynamically, e.g. building the ship?

Can it be done without modifying the engine?

6 Likes

It’s 2023 and we’re still facing the same issue. Please keep me posted if there are any updates.

thx

My game has moving objects that characters need to jump on, climb, and move on top of. It is a top-down style game with multiple selectable characters that you click to move, each using AI movement methods. The objects that these Characters are on top of move all across the map, so I assume it is similar to the Sea of Thieves situation. Therefore I have decided to try to use Sea of Thieves method to accomplish this.

Even though I am relatively experienced in C++, doing this kind of hacky solution has me nervous. I want to make sure I’m not going to do this in a suboptimal way, so I’ll describe my plan here. My thought is to give each character an invisible character clone that navigates on the original static mesh, and that information is sent back to the “real” character. It seems like I am forced to use invisible characters if I want to use Detour Crowd Avoidance. Am I wrong about that? I’d love to hear feedback in case this leads to performance problems that I can’t easily solve.

Any advice is appreciated, thanks.

1 Like

I got the Sea of Thieves method to work in the way I described, including with Detour Crowd Avoidance. I did it in c++. It didn’t take long to do but there were some tricky aspects. I recommend people go this route, it’s not that hard to do.

I haven’t done rotation yet, but I assume all that requires is applying some rotation math to the clicked point in addition to the regular XYZ translation. Am about to finish implementing jumping from NavLinkProxy with it.

2 Likes

are you able to do a tutorial on this please?

This is something I’d also love to see a tutorial about!

you mention the Crew AI, but how about the ships navigation is suppose to work? for instance in case the real ship is affected by the wave the cloned ship won’t be affected by the waves, so how the ship is suppose to navigate back and forth between the clone and the original ship?

somebody help! HELP!

Hello, so I was working on this problem for a while, which similar problems exists in other engines too. Some of them uses local volumes, moving generations etc.

When it comes to Unreal for sure the engine can be modified to have this however custom engine versions is not a good choice if we want to keep up with the features coming up with UE’s each release since there are multiple systems dependent on it. To have custom navigation system would need custom feature modifications in engine too, even one update in any of those systems can make things go south.

Just to give some context Unreal doesn’t really exposes detour recast internals in the navigation system (which we can) however that’s also a modification and have other blockers.

  • In practice AI expects a primary RecastNavMesh. Multiple navmeshes can exist, but the engine heavily assumes a single main navmesh for AI queries and movement.
  • AI movement (PathFollowingComponent, crowd system, smart nav links) all assume a single shared navmesh, so even when data is abstracted, the underlying queries still route through it.
  • There are some workarounds on it as mentioned, however they are not super reliable because the navigation system is fundamentally tied to static world-space data. When a platform moves, the tile references and path data become invalid, so native navigation cannot correctly update or remap paths for dynamic transforms.

While working I experimented with many methods for a nice design architecture, mostly around current navigation system, since going a complete different solution (fully new navigation system) is not really necessary. Navigation works, is quite robust with agents etc. When platforms use physics or dynamic transforms, native navigation cannot keep up, causing offset drift or invalid paths so I took the approach of using Unreal’s base but doing my own local navigation based on same principles but using splines in the end to keep it really strict and controllable.

Simply

  • Create a component that extracts navigation data for me with some specs that I want.
  • Use this abstract data to create local paths converted to splines of movement on platforms.
  • Make movement over the abstract splines on tick, relying only XY but also use AI movement abilities already existing.
  • Upon reach or success create callbacks of movement complete, remove splines and give back controls to AI.

This allowed me to do deterministic platform local movement, not effected from anything at all ( if we want we can do those also). Right now it’s open ended and intentionaly didn’t create the further aspects of it such as

-Z acceleration changes and reactions not implemented. This I beleive should be a custom movement aspect on ship if we want that depending on the game.
-Avoidance of path crossings. This can be done with other things as well but not implemented.
-Data points are voxels right now, but in the future they could evolve toward a more polygon-based structure similar in spirit to Unreal’s navmesh. This would give smoother paths, but it’s not required unless the game needs more complex layouts.
-Onboarding and Offboarding to moving platform system is not implemented. Simply this is a seperate system which we have to tell unreal’s system to explicitly use MGDN upon close to it or on overlap. Which is not a big thing however I left those things open ended. Some games could only require local movements sometimes not.

World → Moving Platform (Ship, Train, Plane) → World flow can be achieved by query the volumes that are already existing in the subsystem.

So the plugin is here.

I played with it quite a while, there could be bugs but in the end this is a TPOC which demonstrates the architecture to approach it for sure it can be further advanced and customised solving local navigation problems without touching core engine systems but taking advantage of it.

There is quite a documentation of how it works and what it can do on readme.

Here is a demo of it working on multiple physics based moving ships, multiple AI agents and multiple path generation all in localspace.

Let me know if this is something desirable and makes sense. Also any one feel free to contribute so we can advance plugin further a bit more. For sure this would be better if we do on engine code however these are all related to choices and their outcomes for the features that are dependent on the navigation framework.

Edit : Also added some basic repath / avoidance functions in it (Collision Sweep based)

  • Upon obstacle creates a new path with detour and replaces current path spline with new points, seamlessly continue movement.
  • Upon obstacle encountered more than 2, detour created with a wait delay before continue movement.
  • Various helper functions : IsPawnOnMovingPlatform(), IsControllerOnMovingPlatform(), GetPawnPlatform(), GetAllNavigationVolumes()
  • Direct movement functions MoveDirectMGDNAsync() from out of moving platform or to serve the basis of bridge between UE native navmesh and MGDN. It is now possible to check with AI which nav system to use.
  • Various improvements on data creation, navmesh detection, Z correction and as results splines of paths are truly created on the correct Z alignment even though Z generally on movement component.
  • Simple agent detection added for path and spline creation considering agent radius, navigation data, with addition of ability find a closest navigatable point on grid.

Basic detour and avoidance

Basic direct move to

4 Likes