Пример #1
0
    /// <summary>
    /// Instantiates a GameObject showing connections between <see cref="RoadLatticeNode"/>s without
    /// distinguishing disjoint partitions of the road graph.
    /// </summary>
    /// <param name="lattice">The lattice from which to generate a GameObject</param>
    /// <param name="indicateNodes">Whether to add markers at each node</param>
    /// <param name="material">The material to apply to the generated mesh</param>
    /// <returns>The GameObject representation of the supplied lattice</returns>
    private static GameObject MakeUnpartitionedLatticeDebugGameObject(
        RoadLattice lattice, bool indicateNodes, Material material)
    {
        GameObject latticeParent = new GameObject();

        latticeParent.name = "Road Lattice";
        List <Vector2>            vertices  = new List <Vector2>();
        List <RoadLatticeNode>    nodes     = lattice.GetNodes();
        HashSet <RoadLatticeNode> processed = new HashSet <RoadLatticeNode>();

        foreach (RoadLatticeNode node in nodes)
        {
            if (processed.Contains(node))
            {
                continue;
            }

            if (indicateNodes)
            {
                MakeRoadLatticeNodeIndicator(node, latticeParent);
            }

            processed.Add(node);
            foreach (RoadLatticeNode neighbor in node.Neighbors)
            {
                vertices.Add(node.Location);
                vertices.Add(neighbor.Location);
            }
        }

        MakeSublatticeMeshes(latticeParent, vertices, material);
        return(latticeParent);
    }
Пример #2
0
        protected void PathTo(Vector3 endPosition)
        {
            // Snap start/end positions to road lattice nodes
            RoadLatticeNode startNode =
                BaseMapLoader.MapsService.RoadLattice.SnapToNode(transform.position);
            RoadLatticeNode endNode = BaseMapLoader.MapsService.RoadLattice.SnapToNode(endPosition);

            // Find path between start/end nodes
            PathToDestination = RoadLattice.UncheckedFindPath(startNode, endNode, PathSearchLimit);

            // Reset our pathfinding instructions - waypoint at index 0 is our start position
            WaypointIndex = 0;

            if (PathToDestination != null && PathToDestination.Count > 0)
            {
                // Init navigation details - our next target is the waypoint after the start position
                CurrentTargetPosition = new Vector3(
                    PathToDestination[WaypointIndex].Location.x,
                    transform.position.y,
                    PathToDestination[WaypointIndex].Location.y);
                IsMoving = true;
            }
            else
            {
                IsMoving = false;
            }

            DisplayRoute(PathToDestination);
        }
Пример #3
0
    /// <summary>
    /// Receives two game objects, snaps them to the current road lattice, and displays the shortest
    /// path between them.
    /// </summary>
    /// <remarks>
    /// Can be attached as a Unity event handler to the
    /// <see cref="RoadLatticePathFindingObjectMover.UpdatedPositions"/> UnityEvent.
    /// </remarks>
    /// <param name="start">The path start object.</param>
    /// <param name="end">The path end object.</param>
    public void CreatePathBetweenObjects(GameObject start, GameObject end)
    {
        if (PathDisplay != null)
        {
            Destroy(PathDisplay);
        }

        RoadLatticeNode startNode = MapsService.RoadLattice.SnapToNode(start.transform.position);
        RoadLatticeNode endNode   = MapsService.RoadLattice.SnapToNode(end.transform.position);

        start.transform.position = new Vector3(startNode.Location.x, 0, startNode.Location.y);
        end.transform.position   = new Vector3(endNode.Location.x, 0, endNode.Location.y);
        List <RoadLatticeNode> path =
            RoadLattice.UncheckedFindPath(startNode, endNode, PathSearchLimit);

        if (path == null)
        {
            Debug.LogFormat("No path found!");
        }
        else
        {
            PathDisplay = MakeRouteDisplay(path);
            PathDisplay.transform.Translate(Vector3.up * PathDisplayY);
        }
    }
Пример #4
0
        /// <summary>
        /// Instantiates a GameObject showing connections between <see cref="RoadLatticeNode"/>s,
        /// creating a separate mesh for each road priority, and assigning materials based on priority.
        /// </summary>
        /// <param name="lattice">The lattice from which to generate a GameObject</param>
        /// <param name="materials">The materials to apply to the generated meshes</param>
        /// <param name="indicateNodes">Whether to add markers at each node</param>
        /// <returns>The GameObject representation of the supplied lattice</returns>
        public static GameObject MakeAttributedLatticeDebugGameObject(
            RoadLattice lattice, Material[] materials, bool indicateNodes)
        {
            GameObject latticeParent = new GameObject();

            latticeParent.name = "Road Lattice";

            // One set of mesh vertices per road priority, plus one for the default.
            List <Vector2>[] vertices = new List <Vector2> [RoadPriorities.Length + 1];

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = new List <Vector2>();
            }

            List <RoadLatticeNode>    nodes     = lattice.GetNodes();
            HashSet <RoadLatticeNode> processed = new HashSet <RoadLatticeNode>();

            foreach (RoadLatticeNode node in nodes)
            {
                if (indicateNodes)
                {
                    MakeRoadLatticeNodeIndicator(node, latticeParent);
                }

                foreach (RoadLatticeEdge edge in node.Edges)
                {
                    if (processed.Contains(edge.Target))
                    {
                        continue;
                    }

                    // Map the road priority to the supplied materials using the RoadPriorities array.
                    int index =
                        (Array.IndexOf(RoadPriorities, edge.Segment.Metadata.Usage) + 1) % vertices.Length;
                    vertices[index].Add(node.Location);
                    vertices[index].Add(edge.Target.Location);
                }

                processed.Add(node);
            }

            for (int i = 0; i < vertices.Length; i++)
            {
                MakeSublatticeMeshes(latticeParent, vertices[i], materials[i % materials.Length]);
            }

            return(latticeParent);
        }
Пример #5
0
 /// <summary>
 /// Instantiates a GameObject showing connections between <see cref="RoadLatticeNode"/> objects.
 /// </summary>
 /// <param name="lattice">The lattice from which to generate a GameObject</param>
 /// <param name="materials">
 /// The material(s) to apply to the created RoadLattice object</param>
 /// <param name="indicateNodes">Whether to add markers at each node</param>
 /// <param name="showPartitioning">
 /// Whether to create separate debug objects for each independent, contiguous sub-lattice
 /// </param>
 /// <returns>The GameObject representation of the supplied lattice</returns>
 public static GameObject MakeRoadLatticeDebugGameObject(
     RoadLattice lattice, Material[] materials, bool indicateNodes, bool showPartitioning)
 {
     if (materials == null || materials.Length == 0)
     {
         materials = new Material[] { null };
     }
     if (!showPartitioning)
     {
         return(MakeUnpartitionedLatticeDebugGameObject(lattice, indicateNodes, materials[0]));
     }
     else
     {
         return(MakePartitionedRoadLatticeDebugGameObject(lattice, indicateNodes, materials));
     }
 }
Пример #6
0
    /// <summary>
    /// Instantiates a GameObject showing connections between <see cref="RoadLatticeNode"/>s using
    /// materials to distinguish disjoint partitions of the road graph.
    /// </summary>
    /// <param name="lattice">The lattice from which to generate a GameObject</param>
    /// <param name="indicateNodes">Whether to add markers at each node</param>
    /// <param name="materials">The materials to apply to the disjoint sub-lattices</param>
    /// <returns>The GameObject representation of the supplied lattice</returns>
    private static GameObject MakePartitionedRoadLatticeDebugGameObject(
        RoadLattice lattice, bool indicateNodes, Material[] materials)
    {
        // A list for collecting road segment end point locations.
        List <Vector2> vertices = new List <Vector2>();
        // A set of nodes with connections to other nodes that have all been converted into geometry.
        HashSet <RoadLatticeNode> processed = new HashSet <RoadLatticeNode>();

        int        materialIndex = 0;
        GameObject latticeParent = new GameObject();

        latticeParent.name = "Road Lattice Parent";
        List <RoadLatticeNode> nodes = lattice.GetNodes();

        foreach (RoadLatticeNode node in nodes)
        {
            // Skip this node if it has already had all its connections turned into geometry, otherwise
            // use it as the starting node for a new disjoint sub-lattice representation.
            if (processed.Contains(node))
            {
                continue;
            }
            vertices.Clear();
            // A set of nodes reachable from the set of nodes that have been processed so far. Note: this
            // list may contain nodes that have already been processed if such ndoes are reachable from
            // more than one neighbouring node.
            Stack <RoadLatticeNode> reachableNodes = new Stack <RoadLatticeNode>();
            reachableNodes.Push(node);
            // Keep processing nodes til we have visited all reachable nodes.
            while (reachableNodes.Count > 0)
            {
                RoadLatticeNode source = reachableNodes.Pop();
                // Skip nodes we have previously processed by reaching them through an alternative path.
                if (processed.Contains(source))
                {
                    continue;
                }
                if (indicateNodes)
                {
                    MakeRoadLatticeNodeIndicator(source, latticeParent);
                }
                // Mark this node as processed, add segments for all its connections, and add all its
                // neighbours to the reachable set.
                processed.Add(source);
                foreach (RoadLatticeNode neighbor in source.Neighbors)
                {
                    if (!processed.Contains(neighbor))
                    {
                        vertices.Add(source.Location);
                        vertices.Add(neighbor.Location);
                        reachableNodes.Push(neighbor);
                    }
                }
            }
            GameObject go = new GameObject();
            go.name = "Road Lattice";
            MakeSublatticeMeshes(go, vertices, materials[materialIndex]);
            materialIndex       = (materialIndex + 1) % materials.Length;
            go.transform.parent = latticeParent.transform;
        }

        return(latticeParent);
    }