コード例 #1
0
        public int GetDistance(PlatformerPathNode nodeA, PlatformerPathNode nodeB)
        {
            int dstX = (int)Mathf.Abs(nodeA.gridPosition.x - nodeB.gridPosition.x);
            int dstY = (int)Mathf.Abs(nodeA.gridPosition.y - nodeB.gridPosition.y);

            if (dstX > dstY)
            {
                return(14 * dstY + 10 * (dstX - dstY));
            }
            else
            {
                return(14 * dstX + 10 * (dstY - dstX));
            }
        }
コード例 #2
0
        void RetracePath(PlatformerPathNode startNode, PlatformerPathNode endNode)
        {
            path      = new List <PlatformerPathNode>();
            pathLinks = new List <PlatformerPathLink>();
            PlatformerPathNode currentNode = endNode;

            while (currentNode != startNode)
            {
                path.Add(currentNode);
                for (int i = 0; i < gridData[currentNode.parent].links.Count; i++)
                {
                    if (currentNode.links[i].endNode == currentNode.gridIndex)
                    {
                        pathLinks.Add(currentNode.links[i]);
                    }
                }
                currentNode = grid.gridData.grid[currentNode.parent];
            }
            path.Reverse();
            pathLinks.Reverse();
        }
コード例 #3
0
        public void FindPath(Vector2 startPos, Vector2 targetPos)
        {
            PlatformerPathNode startNode = grid.NodeFromWorldPoint(startPos);
            PlatformerPathNode endNode   = grid.NodeFromWorldPoint(targetPos);

            List <PlatformerPathNode>    openSet   = new List <PlatformerPathNode>();
            HashSet <PlatformerPathNode> closedSet = new HashSet <PlatformerPathNode>();


            PlatformerPathNode startOffset = null;
            PlatformerPathNode endOffset   = null;

            if (startNode.nodeType == PlatNodeType.none || startNode.nodeType == PlatNodeType.blocked)
            {
                startOffset = grid.FindNeighbouringValidNode(startNode);
                if (startOffset == null)
                {
                    if (startNode.nodeType == PlatNodeType.none)
                    {
                        startOffset = grid.FindValidNodeBelow(startNode);
                    }
                    else
                    {
                        startOffset = grid.FindNeighbouringOpenNode(startNode);
                        if (startOffset == null && startNode.nodeType == PlatNodeType.blocked)
                        {
                            Debug.Log("Something has gone horribly wrong with the starting node, aborting.");
                        }
                        else
                        {
                            startOffset = grid.FindValidNodeBelow(startOffset);
                        }
                    }
                }
            }

            if (endNode.nodeType == PlatNodeType.none || endNode.nodeType == PlatNodeType.blocked)
            {
                endOffset = grid.FindNeighbouringValidNode(endNode);
                if (endOffset == null)
                {
                    if (endNode.nodeType == PlatNodeType.none)
                    {
                        endOffset = grid.FindValidNodeBelow(endNode);
                    }
                    else
                    {
                        endOffset = grid.FindNeighbouringOpenNode(endNode);
                        if (endOffset == null && endNode.nodeType == PlatNodeType.blocked)
                        {
                            Debug.Log("Something has gone horribly wrong with the target node, aborting.");
                        }
                        else
                        {
                            endOffset = grid.FindValidNodeBelow(endOffset);
                        }
                    }
                }
            }

            if (startOffset != null)
            {
                startNode = startOffset;
            }
            if (endOffset != null)
            {
                endNode = endOffset;
            }

            openSet.Add(startNode);
            while (openSet.Count > 0)
            {
                PlatformerPathNode currentNode = openSet[0];
                for (int i = 1; i < openSet.Count; i++)
                {
                    if (openSet[i].fCost < currentNode.fCost || openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost)
                    {
                        currentNode = openSet[i];
                    }
                }

                openSet.Remove(currentNode);
                closedSet.Add(currentNode);

                if (currentNode == endNode)
                {
                    RetracePath(startNode, endNode);
                    return;
                }

                for (int i = 0; i < gridData[currentNode.gridIndex].links.Count; i++)
                {
                    PlatformerPathLink l = gridData[currentNode.gridIndex].links[i];

                    if (closedSet.Contains(gridData[l.endNode]))
                    {
                        continue;
                    }

                    int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, gridData[l.endNode]);
                    if (newMovementCostToNeighbour < gridData[l.endNode].gCost || !openSet.Contains(gridData[l.endNode]))
                    {
                        gridData[l.endNode].gCost  = newMovementCostToNeighbour;
                        gridData[l.endNode].hCost  = GetDistance(gridData[l.endNode], endNode);
                        gridData[l.endNode].parent = currentNode.gridIndex;

                        if (!openSet.Contains(gridData[l.endNode]))
                        {
                            openSet.Add(gridData[l.endNode]);
                        }
                    }
                }
            }
        }