public Grid(int width, int height, float cellSize, Vector3 originPosition, Func <Grid <TGridObject>, int, int, TGridObject> createGridObject) { this.width = width; this.height = height; this.cellSize = cellSize; this.originPosition = originPosition; gridArray = new TGridObject[width, height]; for (int x = 0; x < gridArray.GetLength(0); x++) { for (int y = 0; y < gridArray.GetLength(1); y++) { gridArray[x, y] = createGridObject(this, x, y); } } bool showDebug = true; if (showDebug) { TextMesh[,] debugTextArray = new TextMesh[width, height]; for (int x = 0; x < gridArray.GetLength(0); x++) { for (int y = 0; y < gridArray.GetLength(1); y++) { debugTextArray[x, y] = DebugDrawer.CreateWorldText(gridArray[x, y]?.ToString(), null, GetWorldPosition(x, y) - Vector3.one * 0.5f + new Vector3(cellSize, cellSize) * .5f, 20, Color.white, TextAnchor.MiddleCenter); Debug.DrawLine(GetWorldPosition(x, y) - Vector3.one * 0.5f, GetWorldPosition(x, y + 1) - Vector3.one * 0.5f, Color.white, 100f); Debug.DrawLine(GetWorldPosition(x, y) - Vector3.one * 0.5f, GetWorldPosition(x + 1, y) - Vector3.one * 0.5f, Color.white, 100f); } } Debug.DrawLine(GetWorldPosition(0, height) - Vector3.one * 0.5f, GetWorldPosition(width, height) - Vector3.one * 0.5f, Color.white, 100f); Debug.DrawLine(GetWorldPosition(width, 0) - Vector3.one * 0.5f, GetWorldPosition(width, height) - Vector3.one * 0.5f, Color.white, 100f); } }
public List <PathNode> FindPath(int startX, int startY, int endX, int endY, bool forced = false) { PathNode startNode = grid.GetGridObject(startX, startY); PathNode endNode = grid.GetGridObject(endX, endY); var possibleFinalNodes = GetNeighbourList(endNode); if (possibleFinalNodes == null || possibleFinalNodes.Count == 0) { return(null); } for (int i = 0; i < possibleFinalNodes.Count; i++) { if (!possibleFinalNodes[i].isWalkable) { possibleFinalNodes.Remove(possibleFinalNodes[i]); } } if (possibleFinalNodes.Count == 0) { return(null); } DebugDrawer.DeleteCreateWorldText(); if (startNode == null || endNode == null) { // Invalid Path return(null); } openList = new List <PathNode> { startNode }; closedList = new List <PathNode>(); for (int x = 0; x < grid.GetWidth(); x++) { for (int y = 0; y < grid.GetHeight(); y++) { PathNode pathNode = grid.GetGridObject(x, y); pathNode.gCost = 99999999; pathNode.CalculateFCost(); pathNode.cameFromNode = null; } } startNode.gCost = 0; startNode.hCost = CalculateDistanceCost(startNode, endNode); startNode.CalculateFCost(); while (openList.Count > 0) { PathNode currentNode = GetLowestFCostNode(openList); if (currentNode.Equals(endNode) || possibleFinalNodes.Contains(currentNode)) { // Reached final node return(CalculatePath(currentNode)); } openList.Remove(currentNode); closedList.Add(currentNode); foreach (PathNode neighbourNode in GetNeighbourList(currentNode)) { if (closedList.Contains(neighbourNode)) { continue; } /* Code for optimizing pathfinding with multiblocks; * if (neighbourNode.structure is IMultipleNodesStructure) //Adding all other occupied nodes from the multiblock to the closedlist; * { * List<PathNode> disposableNodes = (neighbourNode.structure as IMultipleNodesStructure).getPathNodeList(); * foreach (var node in disposableNodes) * { * closedList.Add(node); * } * } */ if (!neighbourNode.isWalkable && !forced) { closedList.Add(neighbourNode); continue; } int tentativeGCost = currentNode.gCost + CalculateDistanceCost(currentNode, neighbourNode); if (tentativeGCost < neighbourNode.gCost) { neighbourNode.cameFromNode = currentNode; neighbourNode.gCost = tentativeGCost; neighbourNode.hCost = CalculateDistanceCost(neighbourNode, endNode); neighbourNode.CalculateFCost(); DebugDrawer.CreateWorldText(neighbourNode.hCost.ToString(), null, grid.GetWorldPosition(neighbourNode.x, neighbourNode.y) - Vector3.one * 0.2f + new Vector3(grid.GetCellSize(), grid.GetCellSize()) * .5f, 20, neighbourNode.isWalkable ? Color.white : Color.red, TextAnchor.MiddleCenter); if (!openList.Contains(neighbourNode)) { openList.Add(neighbourNode); } } //PathfindingDebugStepVisual.Instance.TakeSnapshot(grid, currentNode, openList, closedList); } } // Out of nodes on the openList return(null); }