// 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)); }
public void Reset() { Parent = null; GCost = Mathf.Infinity; HCost = Mathf.Infinity; }
public float NonWalkableNeighborsCost(PathfindingNode node) { List <PathfindingNode> nonWalkableNeighbors = GetNeighbors(node).Where(neighbor => !neighbor.IsWalkable).ToList(); return(nonWalkableNeighbors.Count); }