Search Unity

Feedback Getting Navigation Meshes (NavMesh) to work with Entities 1.0

Discussion in 'Entity Component System' started by ShiftyCo, Jan 25, 2023.

  1. ShiftyCo

    ShiftyCo

    Joined:
    Nov 19, 2015
    Posts:
    3
    This post is for people who want to get AI navigation across meshes to work with ECS entities in a performant manner. There have been a number of related posts on the topic, but all the others seem to focus on rolling your own solution, and many of the custom solutions described weren't updated to Entities 1.0. As far as I can find, there is no post describing how to get the current Navigation system to work in the ECS framework.

    To start, this uses the Unity.Experimental.AI portion of NavMesh, which is focused around getting NavMeshes to work with Unity Jobs. This is 90% of the work, since is allows us to run schedule performant queries in ECS. The other 10% of the work is the NavMeshSurface class. The NavMeshSurface component defines what surfaces can be traversed, and is notably not ECS compatible. This means no* NavMeshSurfaces in subscenes, because they will not be registered and cannot be queried against. Surfaces in the main scene will be query-able though, since all navmeshes are connected in a single world, accessible with NavMeshWorld.GetDefaultWorld().

    This is still a problem however, as while you can bake the geometry in subscenes, the NavMeshSurfaces storing the data have to be stored in the main scene. This makes it hard to dynamically add geometry if you want to load sub-scene geometry during a later point in time. Fortunately there is a simple solution.

    *You can place the NavMeshSufrace in a subscene, but have a System Instantiate it as a GameObject in the main scene. Since the NavMeshSurface automatically registers itself on enable, you don't even have to worry about it being available.

    I've attached a script that contains the Authoring and system to make a NavMeshSurface from an ECS subscene work in the main scene. Just add the component "NavMeshSurfaceAuthoring" for the NavMeshSurface's in subscenes and it will work for queries.
     

    Attached Files:

    Bruce_Bruce and plat8899 like this.
  2. ShiftyCo

    ShiftyCo

    Joined:
    Nov 19, 2015
    Posts:
    3
    I've also just learned that you can shorten this process by taking the NavMeshData that was baked and store it directly in an Authored component. Then during runtime add the data directly with the method:
    Code (CSharp):
    1. NavMesh.AddNavMeshData(NavMeshData data);
    When doing it with this method, the data also has to be removed when the stored entity is removed, else you will leak navmesh data.
     
    Bruce_Bruce and plat8899 like this.
  3. Bruce_Bruce

    Bruce_Bruce

    Joined:
    Oct 2, 2023
    Posts:
    1
    Just wanted to say thank you for this!