Saving and Loading Graphs
How to precalculate graphs and store that data.
All graphs can be saved and loaded from files. This is actually what the editor does all the time; barely any Unity serialization is used. Instead, all graph settings are serialized and stored in a byte array. However, not only settings can be saved. Once calculated, a graph can save all nodes to a compact byte array representation, which can then be saved to a file and loaded somewhere else.
In the A* inspector, under the Save & Load tab, there are two buttons named "Save to file" and "Load from file". These can be used to save and load graph files.
Caching Graph Calculation
Recalculating the graphs at startup is usually what you want, but sometimes - especially if you are using the RecastGraph or developing for mobile - the lag at the start can get very annoying. It might also be the case that you cannot calculate the graph at startup for some reason.
In that case, graph caching is great. It enables you to scan the graph in the editor and save it to an external file which will be loaded at startup. It is a lot faster than scanning the graphs in most cases and you know exactly how the graph will look.
To create a cache, open the Save & Load tab in the A* inspector and click Generate Cache. It will also ask you if you want to rescan the graph before saving. Now the graph you saved will be loaded with all node info intact at startup, with no calculation time necessary.
Saving Graphs to File and Loading them
You might also want to save the graphs to a file which you can load later. You can even load it during runtime from a server, for example.
If you want to save your graphs, open the Save & Load tab, and click the Save to file button. You can either include only the settings, or include settings as well as node data. If you only include settings, then after the graph has been loaded, you will need to recalculate it before any characters can use it for navigation. You can recalculate all graphs using:
AstarPath.active.Scan();
When you want to load the graphs again, simply press the Load from file button and locate the file. Note that this will replace your current graphs.
Loading and Saving using Code
If you want to load or save graphs during runtime, you cannot use the editor interface for obvious reasons.
There is an easy-to-use API for saving and loading files.
This will serialize graph settings to a byte array. By default, node info is included (assuming the graphs have been scanned first). byte[] bytes = AstarPath.active.data.SerializeGraphs();
If you want more control, you can add some settings var settings = new Pathfinding.Serialization.SerializeSettings();
To load the saved data you can call:
// Only save settings
settings.nodes = false;
byte[] bytes = AstarPath.active.data.SerializeGraphs(settings);AstarPath.active.data.DeserializeGraphs(bytes);
If you only load settings, you may want to call Scan after you have loaded the settings: AstarPath.active.data.DeserializeGraphs(bytes);
AstarPath.active.Scan();
Additive Loading
Instead of replacing the currently loaded graphs, you can additively load graphs using
AstarPath.active.data.DeserializeGraphsAdditive(bytes);
You can unload graphs using
var data = AstarPath.active.data;
var myGraph = data.gridGraph;
data.RemoveGraph(myGraph);
Including Data in a TextAsset
Graph data can be included in textassets for easier inclusion in the build. When you have saved the data to a file, rename that file to something like "myGraph.bytes" and place it in your Unity Project. This will tell Unity to handle it as binary information. With an extension like .txt, the data would get corrupted because Unity would try to read it as text. Some operating systems like to hide the extension, so if Unity doesn't seem to recognize the file with the .bytes extension, make sure it really has a .bytes extension; the .zip (or other) extension might just be hidden. Then you can load the graph from a text asset by referencing it in a variable, and accessing the .bytes field. using UnityEngine;
using System.Collections;
using Pathfinding;
public class TestLoader : MonoBehaviour {
public TextAsset graphData;
// Load the graph when the game starts
void Start () {
AstarPath.active.data.DeserializeGraphs(graphData.bytes);
}
}
Internal Data Structure
All settings are serialized to JSON. This is a good way to keep it forwards and backwards compatible. All files referred to below are compressed into a single zip file to make the size smaller and make it easier to handle the data. This means you can actually open the zip file and edit the settings manually.
Many of the files mentioned below are not always included in the zip. If it is determined that a file would not contain any relevant information (such as saving user created connections, but no connections have been created), it is left out.
Meta
A meta.json file is present in all serializations. This file contains information which is not connected to a specific graph, or is needed to load the other graphs.
The meta file contains:
Version number for the system
Number of graphs which are saved
GUID values for each graph, to identify them
Type of each graph
Below is an example of a meta.json file: {
"version": "3.0.9.5",
"graphs": 1,
"guids":
[
"0d83c93fc4928934-8362a8662ec4fb9d"
],
"typeNames":
[
"Pathfinding.GridGraph"
]
}
Graph Settings
Settings for each graph are stored as "graph#.json" where # is the graph number. Here is an example of serialized settings for a grid graph (with some settings removed to keep the length down): {
"aspectRatio":1,
"rotation":{
"x":0,
"y":0,
"z":0
},
"center":{
"x":0,
"y":-0.1,
"z":0
},
"unclampedSize":{
"x":100,
"y":100
},
"nodeSize":1,
"maxClimb":0.4,
"maxClimbAxis":1,
"maxSlope":90,
"erodeIterations":0,
"autoLinkGrids":false,
"autoLinkDistLimit":10,
"neighbours":"Eight",
"cutCorners":true,
"penaltyPositionOffset":0,
"penaltyPosition":false,
"penaltyPositionFactor":1,
"penaltyAngle":false,
"penaltyAngleFactor":100,
"open":true,
"infoScreenOpen":false
...
}
Node information (if included in the serialized data) would take too much space to be included as JSON; instead, it is written as binary data. Each graph type has its own code for serializing node data. This is handled by the SerializeExtraInfo and DeserializeExtraInfo methods on each graph.
User Created Connections
If you use any NodeLink2 components in the scene, keep in mind that they are not serialized with the graph data. If you want to preserve them, you will have to save them separately.