Combining recast graphs

Hi everyone!
First of all, I’m sorry for my English )
I’m also new to all this stuff, so I’m not sure if this is a correct place for the topic.

So, what I’m trying to do is to make different navmeshes and combine them at runtime.
I have an empty scene which is all walkable. Then as game starts, obstacles are generated from prefabs.
But it takes to long to generate final navmesh at runtime. So is there any way pregenerate obstacles’ navmeshes and combine those navmeshes at runtime?

Hi Djebedia,

I had the same question a month or so ago.

I’ve found the documentation on how to additively serialize the data with:

AstarPath.active.data.DeserializeGraphs(loadgraph1.bytes); //to load extra graphs via textasset

To create them go to your Astar gameobject in the scene and under Save & Load save as File:
image

To remove old graphs no longer needed you will have to run:
data.RemoveGraph(myGraph); //removes the entire Astar graph in your script

I hope this helps get you started as long as your obstacles are not going to be procedural.

If they are, you’ll have to run the:

Bounds bounds = prefab.transform.GetComponent().bounds;
Astar.GetComponent().UpdateGraphs(bounds); //to update at that specific point.

I hope this helps and If i’m mistaken from my logic at the moment. Aron can correct me.

For a practical script that I’ve made recently (still updating but should help to start)

image

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;

public class LoadPathfinding : MonoBehaviour
{
    public TextAsset watergraph1; //graphs we made in astar save to file
    public TextAsset loadgraph1;  //graphs we made in astar save to file
    public TextAsset loadgraph2;  //graphs we made in astar save to file

    public bool watergraph1set;
    public bool loadgraph1set;
    public bool loadgraph2set;
    public bool loaded1;

    public bool unload;

    // Start is called before the first frame update
    void Start()
    {
        byte[] bytes = AstarPath.active.data.SerializeGraphs(); //allows for more control still working on this to learn it more

        loadgraph1set = true;
    }

    // Update is called once per frame
    void Update()
    {
        if (watergraph1set)
        {
            AstarPath.active.data.DeserializeGraphsAdditive(watergraph1.bytes); //adds the graph data into the active navmesh astar creates
            watergraph1set = false; //set bool to false so it doesn't get called everytime
        }

        if (loadgraph1set)
        {
            AstarPath.active.data.DeserializeGraphsAdditive(loadgraph1.bytes); //adds the graph data into the active navmesh astar creates
            loadgraph1set = false; //set bool to false so it doesn't get called everytime
            loaded1 = true;        //set bool of what is currently loaded in scene and what we want to readd once we clear astar navmesh
        }

        if (loadgraph2set)
        {
            AstarPath.active.data.DeserializeGraphsAdditive(loadgraph2.bytes); //adds the graph data into the active navmesh astar creates
            loadgraph2set = false; //set bool to false so it doesn't get called everytime
        }

        if (unload) //called when we want to erase old graphs that can take up lots of memory overtime (especially for big areas)
        {
            var data = AstarPath.active.data; //get all astars navmesh data info
            var myGraph = data.recastGraph;   //get the graph we are using in the scene
            
            if (myGraph != null) //if existing data exists, then we remove it
            {
                data.RemoveGraph(myGraph); //clear all astar navmesh info
            }
            watergraph1set = true; //set what graphs we want updated in our Update function

            if (loaded1)
            {
                loadgraph1set = true; //enable bool to add graph back into the scene
            }

            unload = false; //to not allow the method to be called more than once in update
        }
    }
}

Hi

There is no way to do that, I’m afraid (unless the navmeshes are completely separate and do not connect to each other). However, would recommend that you try out the beta version (A* Pathfinding Project) in which recast graph scanning has been optimized using burst to be significantly faster.

Thanks a lot! My bad I haven’t found it myself in the documentation.
Seems like this is something I need, though I don’t get how those additional graphs get positioned correctly. I’ll try to check this out, at least I have now where to start from.

Thanks again!

Isn’t DeserializeGraphsAdditive() is what I need?
And those navmeshes ARE completly separate and DO NOT connect to each other - so what does it change?

And thanks for reply! )

So I’ve tried saving graph and loading it via DeserializeGraphsAdditive.
But that new unwalkable ares intersect with initial walkable one - see the screenshot
Also, don’t get how to move that additive graph - seems like I have somehow get metadata, change graph position there and then apply that graph
image

Seems like I finally got what you meant )
DeserializeGraphsAdditive just creates additional graph in graphs collection. And even if I can handle positioning there will be just a bunch of separate graphs not connected to each other at all.

But I still have a couple of questions:

  1. Is there a way to invert the recast graph? I’m sure there is no such an option, but just in case )
  2. Is there a way to connect two graphs? I guess there is no such a way, but again, just in case )
  3. How to move the loaded graph? I can read graph#.json in saved zip file, write correct position into it and then load graph via DeserializeGraphsAdditive. But it seems wrong. Probably there is a place inside DeserializeGraphsPartAdditive - I will try to investigate it.
  1. Not sure what you mean by inverting the recast graph… But most likely the answer is no.

  2. Yes, you can use the NodeLink2 component. However this is intended for off-mesh links. I don’t think it will work great for this use case.

  3. You can use RecastGraph.RelocateNodes.
    See RecastGraph - A* Pathfinding Project