public List <NodeItem> GetRoute(Vector3 from, Vector3 to)
    {
        var fromNode = GetNearestNode(from);
        var toNode   = GetNearestNode(to);

        if (fromNode.guid == toNode.guid)
        {
            return(new List <NodeItem>()
            {
                fromNode
            });
        }

        var baseTraversal = new NodeTraversal()
        {
            distance = 0.0f, guids = new List <string>()
            {
            }
        };
        var pathTraversal = GetTraversal(baseTraversal, fromNode, toNode);

        if (pathTraversal == null)
        {
            return(null);
        }
        return(pathTraversal.guids.Select((guid) => nodes[guid].item).ToList());
    }
    public NodeTraversal Clone()
    {
        var clone = new NodeTraversal();

        clone.distance = distance;
        clone.guids    = guids.GetRange(0, guids.Count);
        return(clone);
    }
    private NodeTraversal GetTraversal(NodeTraversal prior, NodeItem next, NodeItem target)
    {
        if (next.isDeactivated)
        {
            return(null);
        }
        NodeTraversal traversal = prior.Clone();

        if (traversal.guids.Count > 0)
        {
            var last = nodes[prior.guids.Last()].item;
            traversal.distance = prior.distance + (last.transform.position - next.transform.position).magnitude;
        }
        traversal.guids.Add(next.guid);
        if (target.guid == next.guid)
        {
            return(traversal);
        }

        var           state             = nodes[next.guid];
        NodeTraversal shortestTraversal = null;

        foreach (var to in state.to.Values)
        {
            if (traversal.guids.Contains(to.item.guid))
            {
                continue;
            }

            var nextTraversal = GetTraversal(traversal, to.item, target);
            if (nextTraversal == null)
            {
                continue;
            }

            if (shortestTraversal == null || nextTraversal.distance < shortestTraversal.distance)
            {
                shortestTraversal = nextTraversal;
            }
        }
        return(shortestTraversal);
    }