A* Pathfinding Project

Serialize different graphs and movable point graph


#1

Hi,
I am making a game where you can move around buildings in which people are walking (inside buildings with random movement)

I want to use point graph to set each building inner bounds in which people can walk. And later user will be able to move buildings around so I need those local graphs to be moved with buildings. People will never leave graphs in their buildings so I don’t need like graph linking etc. Each building with small simple graph for its dwellers.

So I have few questions:

  1. How to save and load single graph? I need separated serialized graphs for each building as there will be like 20 buildings and only few at the same time so saving and loading all of them doesn’t seem reasonable.
  2. Can I find created/loaded graph by name?
  3. How can I do movable graph for buildings? As I understood the best currently possible way is to use approach you used in Movable example. But I really hope there is something simpler and more direct.
  4. How to rescan single graph? I saw something about graph mask. But keeping graph index and then creating a mask for each graph seems like a lot of trouble just to update one of the graphs. Is there like something like Scan(graph)?

Sorry for a lot of questions but I spend hours on forum and docs trying to find answers and didn’t really find them.

Thank you.


#2

Hi

  1. See http://arongranberg.com/astar/docs/save-load-graphs.php
    If the graphs are not too large I wouldn’t worry too much about keeping them all loaded in memory though. A graph that is not used does not impact performance significantly (except when updating graphs in which case there is some overhead).

  2. If you set the names of them you can do something like

    using System.Linq;
    var name = “My Graph Name”;
    NavGraph graph = AstarPath.active.graphs.First(g => g.name == name);

  3. I recommend the same method as is used in the Movable example. I’m sorry it may require some code changes to the movement scripts, but currently it is the only reasonable solution as moving every node in a graph is far too slow since it has to loop over every single node in the graph every frame.

  4. Currently there is unfortunately no such method. This is because if it would be implemented right now it might break in some cases if different graphs have been connected and you just recalculated one of them, I should probably fix this in the future by keeping some extra metadata. For your case it would work sine all your graphs are known to be separate. In this case you can modify the AstarPath.ScanAsync method (or it might be named ScanLoop in the version that you are using) like this

change

 public IEnumerable<Progress> ScanAsync () {

to

public IEnumerable<Progress> ScanAsync (NavGraph targetGraph = null) {

and then change every instance of

if (graphs[i] != null) {

in that method to

if (graphs[i] != null || (targetGraph != null && graphs[i] != targetGraph)) {

Also change the Scan method from

public void Scan () {

to

public void Scan (NavGraph targetGraph = null) {

and change the call to the ScanAsync or ScanLoop method to include the targetGraph parameter.

I think that should make it possible for you to scan a single graph.


#3

@aron_granberg thanks a lot for this solution.

One more question - how to get a random point inside point graph? I need to make a guy wonder around in his house to random points. Thanks a lot.


#4

Hi

You can get a random node on a point graph using something like this

var graph = AstarPath.active.astarData.pointGraph;
var nodes = graph.nodes;
var node = nodes[Random.Range(0, nodes.Length)];
var nodePosition = (Vector3)node.position;