Пример #1
0
        // TODO Add support for LineOfSight to take line width into account
        private bool LineOfSight(PathfindingNode nodeA, PathfindingNode nodeB)
        {
            // Simple limit to the number of cells that can checked in one call
            // Prevents runaway computation
            // TODO Make sure excecution always terminates so this hard limit can be removed
            int limit = 100;
            int count = 0;

            List <PathfindingNode> intersectedNodes = new List <PathfindingNode>();

            var   dir   = ((Vector2)(nodeB.GridPosition - nodeA.GridPosition)).normalized;
            int   signX = Math.Sign(dir.x);
            int   signY = Math.Sign(dir.y);
            float slope = dir.y / dir.x;

            var     currentCell      = nodeA;
            Vector2 lastIntersection = nodeA.GridPosition;
            float   nextX            = nodeA.GridPosition.x + 0.5f * signX;
            float   nextY            = nodeA.GridPosition.y + 0.5f * signY;

            intersectedNodes.Add(currentCell);

            while (currentCell != nodeB)
            {
                if (count >= limit)
                {
                    return(false);
                }

                float   y    = (nextX - lastIntersection.x) * slope + lastIntersection.y;
                Vector2 xInt = new Vector2(nextX, y);
                float   tx   = dir.x == 0 ? Mathf.Infinity : Vector2.Distance(lastIntersection, xInt);

                float   x    = (nextY - lastIntersection.y) / slope + lastIntersection.x;
                Vector2 yInt = new Vector2(x, nextY);
                float   ty   = dir.y == 0 ? Mathf.Infinity : Vector2.Distance(lastIntersection, yInt);

                if (tx == ty)
                {
                    currentCell = NodeAtGridPosition((signX == 1 ? Mathf.CeilToInt(nextX) : Mathf.FloorToInt(nextX)),
                                                     (signY == 1 ? Mathf.CeilToInt(nextY) : Mathf.FloorToInt(nextY)));
                    intersectedNodes.Add(currentCell);
                    intersectedNodes.Add(NodeAtGridPosition(Mathf.FloorToInt(nextX), Mathf.CeilToInt(nextY)));
                    intersectedNodes.Add(NodeAtGridPosition(Mathf.CeilToInt(nextX), Mathf.FloorToInt(nextY)));
                    lastIntersection = xInt;
                    nextX           += 1 * signX;
                    nextY           += 1 * signY;
                }
                else if (tx < ty)
                {
                    currentCell = NodeAtGridPosition((signX == 1 ? Mathf.CeilToInt(nextX) : Mathf.FloorToInt(nextX)),
                                                     (signY == 1 ? Mathf.FloorToInt(nextY) : Mathf.CeilToInt(nextY)));
                    intersectedNodes.Add(currentCell);
                    lastIntersection = xInt;
                    nextX           += 1 * signX;
                }
                else
                {
                    currentCell = NodeAtGridPosition((signX == 1 ? Mathf.FloorToInt(nextX) : Mathf.CeilToInt(nextX)),
                                                     (signY == 1 ? Mathf.CeilToInt(nextY) : Mathf.FloorToInt(nextY)));
                    intersectedNodes.Add(currentCell);
                    lastIntersection = yInt;
                    nextY           += 1 * signY;
                }

                count++;
            }

            return(intersectedNodes.All(n => n.IsWalkable));
        }
Пример #2
0
 public void Reset()
 {
     Parent = null;
     GCost  = Mathf.Infinity;
     HCost  = Mathf.Infinity;
 }
Пример #3
0
        public float NonWalkableNeighborsCost(PathfindingNode node)
        {
            List <PathfindingNode> nonWalkableNeighbors = GetNeighbors(node).Where(neighbor => !neighbor.IsWalkable).ToList();

            return(nonWalkableNeighbors.Count);
        }