[BUG/Feature Request] Custom Graphs Need to be in Same Assembly

When trying to create a custom graph (such as the example polar graph) they have to be in the same assembly as AstarPath.cs, which meant that I needed to put custom graphs into the same folder as all the other generators, as opposed to in my own folder.

In the documentation, this isn’t mentioned, and I had to dive into the deserialization code to understand why my custom graph wasn’t deserializing. It would cause the inspector to clear out all the created graphs on play, if any of them were in the wrong assembly.

Is there a way we can add documentation around this, or better yet remove this restriction entirely? It would be great to keep my custom graphs in my own folder structure, to make it clear what is premade vs custom.

1 Like

For people who are facing this issue and want a workaround in the meantime, here’s how I fixed it:

Start by creating a file in AstarPathfindingProject -> Generators and name it [CustomGraphName]Wrapper
As you can probably guess, this is going to be a wrapper for your actual implementation, and will be the implementation of NavGraph. Put all of your parameters in here, point your NavGraph editor to this class, and create an Action GetNodesWrapper and a Func ScanInternalWrapper, make them both public or somehow allow them to be set by our wrapped class. Here’s what my ScanInternal and GetNodes look like:

public Action<Action<GraphNode>> GetNodesImplementation;
public Func<IEnumerable<Progress>> ScanInternalImplementation;

public override void GetNodes(Action<GraphNode> action)
{
    GetNodesImplementation?.Invoke(action);
}

protected override IEnumerable<Progress> ScanInternal()
{
    if (ScanInternalImplementation == null)
    {
        yield break;
    }

    foreach (Progress p in ScanInternalImplementation.Invoke())
    {
        yield return p;
    }
}

When you go to set up your graphs, you want to hook together the implementation and the wrapper. I do the actual assignment to the Action and Func from within the implementation’s constructor, but you don’t necessarily have to do it there.

In your actual implementation, make sure that you keep track of the reference, since its the one with all the parameters in it. You can also use it to get at most of the internals of Astar by creating helper functions.

Hope this helps!

Hi

I cannot replicate this using 4.2.3 and Unity 2018.3.0b18. I just created a new polar graph in the root folder of the project (which is not the same assembly because of asmdef files), but it still showed up in the Add Graphs list.

Hey Aron I receive the same problem as juskelis on 2018.3.0f2.

The graph will show up fine in the add graphs list, you can add it and configure it, but when you run the game you will receive an excepting saying it failed to find the graph type and then eventually it will log an error saying there are no graphs in the scene. Once you go back to the Astart Path script component in design mode, you’ll see the custom graph settings have been cleared.

I haven’t debugged it fully but it looks like this is related to line 880 in JsonSerializer.cs:

		Type type = WindowsStoreCompatibility.GetTypeInfo(typeof(AstarPath)).Assembly.GetType(typeNames[index]);

Interestingly AStarData.cs does have a method FindGraphTypes() that does find custom graph types in other assemblies, but that path is not used for this part of the deserialization it seems.

@aron_granberg Same observation as @beebes here, using 4.2.4 in 2018.2.14f1 - Adding the path works fine, but deserialization fails to find the custom graph.

I worked around this by falling back to iterating through all loaded assemblies, similar to what AstarData.FindGraphTypes does:

JsonSerializer.cs#880+

			Type type = WindowsStoreCompatibility.GetTypeInfo(typeof(AstarPath)).Assembly.GetType(typeNames[index]);
			// Fallback to iterating over all loaded assemblies
			if (System.Type.Equals(type, null)) {
				foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies()) {
					type = assembly.GetType(typeNames[index]);
					if (!System.Type.Equals(type, null)) {
						break;
					}
				}
			}

Hi

Thanks for reporting this.
I have uploaded version 4.2.5 now which fixes this bug (or it will be uploaded in a few minutes at least).

You can download it at https://www.arongranberg.com/astar/download

1 Like