A* Pathfinding Project

Scanning a graph programmatically does not work correctly


#1

I’m generating objects and then scanning the graph once at runtime. The graph is already made - I’m simply setting its dimensions and scanning it.

edit: It also seems to not be able to find the graph (using active.data.gridGraph) unless I click on it in the inspector and then click play. Once I click play, inspect another object, exit play, and then go back (so that the grid’s nodes aren’t visible in the editor) the data.gridGraph will once again not exist. Is this project currently not working on 2019.3 / quick play enabled?

// Create collision objects
...

 GridGraph graph = AstarPath.active.data.gridGraph;
            graph.SetDimensions(Mathf.RoundToInt(_worldSize.x) * 2, Mathf.RoundToInt(_worldSize.y) * 2, CellSize.x);

            AstarPath.active.Scan(graph);

Setting the dimensions work correctly, but the graph does not update: https://i.imgur.com/seisMrw.png

However, when I manually scan from the editor it works: https://i.imgur.com/29vcuLD.png

Furthermore, after manually scanning or not, it seems my seeker fails to work correctly; I’m not sure if it has to do with this problem or not.

I find a path and try to move:

_seeker.StartPath(transform.position, Camera.main.ScreenToWorldPoint(f.ScreenPosition), (p) =>
                {
                    _aiPath.SetPath(p);
                });

The path has no errors but it says it is , “ReturnQueue.”


#2

Hi

Depending on your project settings the physics may not be synced yet.
Try calling Physics.SyncTransforms() before scanning the graph.
See https://docs.unity3d.com/ScriptReference/Physics.SyncTransforms.html

This has been fixed in my dev version so that SyncTransform is always called before scanning a graph.


#3

Thanks! This fixed my initial problem, but my other issues remain. Do you want me to make separate posts for them?


#4

I don’t quite understand your other problem. Do you think you could elaborate?


#5

Sure! There are two:

1): I have the pathfinder in its own object. If I play the scene like normally, " AstarPath.active.data.gridGraph" will return null. However, if I click on the object that contains the pathfinder component (and, by doing so, it shows its grid lines in the scene) and then click play, “AstarPath.active.data.gridGraph” will work as intended. Once I exit the scene, click on another object to lose the Pathfinder focus, and click play again, “AstarPath.active.data.gridGraph” will again be null on startup. I’ve been in and out of the project and scene several times, and this happens 100% of the time.

2): I’m trying to find a path and have the AIPath move my object. This is how I currently do it:

_seeker.StartPath(transform.position, Camera.main.ScreenToWorldPoint(f.ScreenPosition), § =>
{
_aiPath.SetPath§;
});

When SetPath is called I get the “You must call the SetPath method with a path that either has been completely […]” exception. However, when I inspect the path that is returned there are no errors and it shows the path in the scene view. The exception is being thrown because the path’s PipelineState is “ReturnQueue.”


#6

Here is a video of the first problem! Hopefully it helps. You can see the first time I play the graph’s lines can be seen in the scene. They disappear after exiting because I don’t have its object selected in the inspector. Once I play the second time the error will appear. https://files.catbox.moe/01w8pd.mp4


#7

Hi

Could you disable the experimental “enter play mode without domain reload” feature? I think it’s possible that is causing some issues.


#8

Thanks! That fixed the first problem but not the second one.


#9

Hi

If you just want to set where the ai should move I suggest you use

ai.destination = Camera.main.ScreenToWorldPoint(f.ScreenPosition);

If you really want to use a custom path for some reason I would suggest that you just do

// Disable the agent's own path recalculation logic
ai.canSearch = false;

var path = ABPath.Construct(transform.position, Camera.main.ScreenToWorldPoint(f.ScreenPosition));
ai.SetPath(path);

This will automatically make the seeker start calculating it.
The AIPath script also uses the seeker component so it may be a bit confused if you start to calculate a path using it directly.

As a bonus, with this approach properties like ai.pathPending will work properly.