- A* version: 5.2.5
- Unity version: 6000.0.29f1
Hi everyone,
I’m trying to generate and crop A* Pathfinding grids directly in the Unity Editor (not at runtime). Everything works perfectly when I press a button in the inspector. Graphs are correctly generated and cropped.
However, when I run a tool that iterates through all my scenes to apply the same operation,the graph modifications are lost when the scenes are reloaded. I’m calling SetDirty
, Undo.RecordObject
, and EditorSceneManager.MarkSceneDirty
, but none of it seems to persist the changes.
Here’s a simplified version of what I’m doing:
[SerializeField] private AstarPath astar;
#if UNITY_EDITOR
public void CreateGrids(Vector3 center, Vector2 size)
{
RecordObject();
astar.data.ClearGraphs();
//My logic to calculate grids bounds
graph.nodeSize = cellSize;
graph.SetDimensions(gridSize.x, gridSize.y, cellSize);
graph.center = center;
graph.Scan();
Crop(graph);
SaveModifications();
}
private static void Crop(GridGraph grid, int margin = 2)
{
//Crop logic
grid.nodeSize = cellSize;
grid.SetDimensions(gridSize.x, gridSize.y, cellSize);
grid.center = center;
grid.Scan();
}
public void RecordObject()
{
if (Application.isPlaying) return;
UnityEditor.Undo.RegisterCompleteObjectUndo(gameObject, "Modify Path Finding");
}
public void SaveModifications()
{
if (Application.isPlaying) return;
UnityEditor.EditorUtility.SetDirty(this);
UnityEditor.EditorUtility.SetDirty(astar);
if(UnityEditor.PrefabUtility.IsPartOfAnyPrefab(gameObject))
UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(gameObject);
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(gameObject.scene);
}
#endif
}
When press “Button” in inspector work perfectly, but when using my scene iteration tools no.
public void IterateAllScenes()
{
CreateActions();
if (actionInstances is not { Count: > 0 }) return;
foreach (var level in allLevels.GetAllLevel())
{
var scene = LoadScene(level);
OnIterateInScene(scene);
}
PrintResult();
}
private Scene LoadScene(LevelData data)
{
return EditorSceneManager.OpenScene($"Assets/Scenes/LevelDatabase/Prototype/{data.SceneName}.unity");
}
private void OnIterateInScene(Scene scene)
{
foreach (var action in actionInstances)
{
action.Do(scene);
}
}
public override void Do(Scene inScene)
{
var grid = FindInScene<PathFindingManager>(scene, true);
if(grid == null) return;
WallToolHelper.GetGroundBound(out var center, out var size);
grid.CreateGrids(center, size);
EditorSceneManager.MarkSceneDirty(inScene);
EditorSceneManager.SaveScene(inScene);
}