Procedural graph generation in edit mode

  • A* version: [enter version here] 5.3.8
  • Unity version: [enter version here] 2023

Hey, guys. I’m attempting to generate graphs procedurally through edit mode, and it doesn’t quite work out. I’m using AstarPath.active.Scan();, which does generate the graphs, and it works when I enter play mode, but this doesn’t seem to update the cache, because it defaults back to where it was before when I exit play mode. Any Ideas on how to get around this would be appreciated.

Hi

By cache, do you mean the cached startup option described here: Saving and Loading Graphs - A* Pathfinding Project?
If so, you need to explicitly save the graph using the button in the inspector for the cache to be updated.

If you mean that your graph settings are just not saved after editing them in edit-mode. You’ll need to serialize the graph settings, if you are not using the unity inspector.

// Edit graphs...
var data = AstarPath.active.data;
data.SetData(data.SerializeGraphs());
UnityEngine.Object.SetDirty(AstarPath.active);

Thanks for the help, Aron! Unfortunately, I was still getting issues with that script. I finally turned to ChatGPT, and a couple of frustrating hours later, came out with this mess. It works, but I don’t completely understand why. Just leaving it here for anyone else who might want this solution in the future. Run this after you’ve made the changes you want to keep in Edit mode.

void RefreshAStarStartupCache_Editor()
    {
#if UNITY_EDITOR
        var astar = AstarPath.active;
        if (!astar) return;

        // Apply pending work and bake nodes
        if (typeof(AstarPath).GetMethod("FlushWorkItems") != null)
            astar.FlushWorkItems();
        astar.Scan();

        // Serialize Nodes + Settings
        Pathfinding.Serialization.SerializeSettings settings;

        var prop = typeof(Pathfinding.Serialization.SerializeSettings).GetProperty("NodesAndSettings");
        if (prop != null)
        {
            // Newer A* exposes a preset
            settings = (Pathfinding.Serialization.SerializeSettings)prop.GetValue(null, null);
        }
        else
        {
            // Older A*: no 'settings' field; just turn on nodes
            settings = new Pathfinding.Serialization.SerializeSettings { nodes = true };
        }

        byte[] bytes = astar.data.SerializeGraphs(settings);

        const string assetPath = "Assets/AStarCache/graphCache.bytes";
        var dir = System.IO.Path.GetDirectoryName(assetPath);
        if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir);
        System.IO.File.WriteAllBytes(assetPath, bytes);
        AssetDatabase.ImportAsset(assetPath);

        var ta = AssetDatabase.LoadAssetAtPath<TextAsset>(assetPath);
        astar.data.file_cachedStartup = ta;
        astar.data.cacheStartup = true;

        EditorUtility.SetDirty(astar);
        EditorSceneManager.MarkSceneDirty(astar.gameObject.scene);
        AssetDatabase.SaveAssets();
        Debug.Log("A* cache refreshed from current editor graphs.");
#endif
    }

type or paste code here