public void OnDrawGizmos() { int debugX = (int)(debugObject.position.x / 160); int debugY = (int)(debugObject.position.z / 160); List <int> connected = navGraph.associatedNodes[debugX, debugY]; foreach (int i in connected) { PortalGraph.PortalNode node = navGraph.nodes[i]; bool horiz = node.isHorizontal; Vector2 nodePos = node.getPosition(); Vector3 position = new Vector3(nodePos.x, 0, nodePos.y); Vector3 size = Vector3.one * 5; if (horiz) { size += Vector3.right * (node.size) * FlowFieldHandler.grid.getSpacing(); } else { size += Vector3.forward * (node.size) * FlowFieldHandler.grid.getSpacing(); } Gizmos.DrawSphere(position, 6); Gizmos.DrawCube(position, size); foreach (int j in node.connectedNodes) { Vector2 nodePos2 = navGraph.nodes[j].getPosition(); Vector3 otherPos = new Vector3(nodePos2.x, 0, nodePos2.y); Debug.DrawLine(position, otherPos); } } for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { Handles.Label(new Vector3(x, 0, y) * 10 + 10 * FlowGrid.gridResolution * new Vector3(debugX, 0, debugY) + Vector3.up * 45, FlowFieldHandler.grid.getBuilding((x + debugX * 16) * 10, (y + debugY * 16) * 10) + ""); } } int subX = (int)(debugObject.position.x % 160) / 10; int subY = (int)(debugObject.position.z % 160) / 10; Handles.Label(debugObject.position, "" + subX + " " + subY); Gizmos.DrawCube(new Vector3((subX + debugX * 16) * 10, 50, (subY + debugY * 16) * 10), Vector3.one * 10); if (subX > 0) { if (FlowFieldHandler.grid.getBuilding(((subX - 1) + debugX * 16) * 10, (subY + debugY * 16) * 10) == -1) { Gizmos.DrawCube(new Vector3(((subX - 1) + debugX * 16) * 10, 50, (subY + debugY * 16) * 10), Vector3.one * 10); } } if (subY > 0) { if (FlowFieldHandler.grid.getBuilding((subX + debugX * 16) * 10, ((subY - 1) + debugY * 16) * 10) == -1) { Gizmos.DrawCube(new Vector3(((subX) + debugX * 16) * 10, 50, (subY - 1 + debugY * 16) * 10), Vector3.one * 10); } } if (subX < 16 - 1) { if (FlowFieldHandler.grid.getBuilding(((subX + 1) + debugX * 16) * 10, (subY + debugY * 16) * 10) == -1) { Gizmos.DrawCube(new Vector3(((subX + 1) + debugX * 16) * 10, 50, (subY + debugY * 16) * 10), Vector3.one * 10); } } if (subY < 16 - 1) { if (FlowFieldHandler.grid.getBuilding((subX + debugX * 16) * 10, ((subY + 1) + debugY * 16) * 10) == -1) { Gizmos.DrawCube(new Vector3(((subX) + debugX * 16) * 10, 50, (subY + 1 + debugY * 16) * 10), Vector3.one * 10); } } return; foreach (PortalGraph.PortalNode node in navGraph.nodes) { bool horiz = node.isHorizontal; Vector2 nodePos = node.getPosition(); Vector3 position = new Vector3(nodePos.x, 0, nodePos.y); Vector3 size = Vector3.one * 5; if (horiz) { size += Vector3.right * (node.size) * 10; } else { size += Vector3.forward * (node.size) * 10; } Gizmos.DrawSphere(position, 6); Gizmos.DrawCube(position, size); foreach (int i in node.connectedNodes) { Vector2 nodePos2 = navGraph.nodes[i].getPosition(); Vector3 otherPos = new Vector3(nodePos2.x, 0, nodePos2.y); Debug.DrawLine(position, otherPos); } } }
public PathRequest calcPath(Vector2 start, Vector2 end, bool reset = false, PathRequest appendTarget = null) { //TODO generating portal maps PathRequest request = (appendTarget == null) ? new PathRequest(grid.getSpacing()) : appendTarget; int startChunkX = (int)(start.x / mapSize); int startChunkY = (int)(start.y / mapSize); int startX = (int)(start.x % mapSize); int startY = (int)(start.y % mapSize); int endChunkX = (int)(end.x / mapSize); int endChunkY = (int)(end.y / mapSize); int endX = (int)(end.x % mapSize); int endY = (int)(end.y % mapSize); //TODO add in detection for which start nodes it has access to. PortalGraph.PortalNode startNode = null; PortalGraph.PortalNode endNode = null; //TODO add an index to the MapDataChunk that stores the index of which portal each square has access to. foreach (int i in navGraph.associatedNodes[startChunkX, startChunkY]) { PortalGraph.PortalNode testNode = navGraph.nodes[i]; int nodeX; int nodeY; if (testNode.isHorizontal) { nodeY = testNode.side ? 0 : FlowGrid.gridResolution - 1; nodeX = testNode.startIndex; } else { nodeX = testNode.side ? 0 : FlowGrid.gridResolution - 1; nodeY = testNode.startIndex; } var mapChunk = mapData[startChunkX, startChunkY]; if (pathfinding.calculatePath(mapChunk, mapChunk.AStarGrid[startX, startY], mapChunk.AStarGrid[nodeX, nodeY], true)) { startNode = testNode; break; } } foreach (int i in navGraph.associatedNodes[endChunkX, endChunkY]) { PortalGraph.PortalNode testNode = navGraph.nodes[i]; int nodeX; int nodeY; if (testNode.isHorizontal) { nodeY = testNode.side ? 0 : FlowGrid.gridResolution - 1; nodeX = testNode.startIndex; } else { nodeX = testNode.side ? 0 : FlowGrid.gridResolution - 1; nodeY = testNode.startIndex; } var mapChunk = mapData[endChunkX, endChunkY]; if (pathfinding.calculatePath(mapChunk, mapChunk.AStarGrid[endX, endY], mapChunk.AStarGrid[nodeX, nodeY], true)) { endNode = testNode; break; } } if (startNode == null) { Debug.LogError("Unit is trapped!"); } if (endNode == null) { Debug.LogError("Requested Destination is inaccessible"); } pathfinding.calculatePath(navGraph, startNode, endNode, reset); List <AStarNode> path = pathfinding.path; FlowGrid finalGrid; Vector2Int pos = new Vector2Int(endChunkX, endChunkY); finalGrid = (!request.chunkSteps.ContainsKey(pos)) ? new FlowGrid() : request.chunkSteps[pos]; finalGrid.integrationField[(int)(end.x % FlowGrid.gridResolution), (int)(end.y % FlowGrid.gridResolution)] = 0; finalGrid.dirtySquares.Add(new Vector2Int((int)(end.x % FlowGrid.gridResolution), (int)(end.y % FlowGrid.gridResolution))); finalGrid.chunkX = endChunkX; finalGrid.chunkY = endChunkY; finalGrid.compute(); if (!request.chunkSteps.ContainsKey(pos)) { request.chunkSteps.Add(pos, finalGrid); } else { request.chunkSteps[pos] = finalGrid; } FlowGrid lastGrid = finalGrid; for (int i = 1; i < path.Count; i++)//trace from the end to the start { PortalGraph.PortalNode last = (PortalGraph.PortalNode)path[i - 1]; PortalGraph.PortalNode current = (PortalGraph.PortalNode)path[i]; Vector2Int portalIndex = new Vector2Int(last.portalX, last.portalY); if (last.gridX != current.gridX || last.gridY != current.gridY) { FlowGrid newGrid; bool hasVisited = request.chunkSteps.ContainsKey(new Vector2Int(current.gridX, current.gridY)); newGrid = hasVisited ? request.chunkSteps[new Vector2Int(current.gridX, current.gridY)] : new FlowGrid(); newGrid.chunkX = current.gridX; newGrid.chunkY = current.gridY; if (last.isHorizontal) { int yIndex = !last.side ? 0 : FlowGrid.gridResolution - 1; int yIndexNot = last.side ? 0 : FlowGrid.gridResolution - 1; for (int j = 0; j < last.size; j++) { newGrid.integrationField[last.startIndex + j, yIndex] = lastGrid.integrationField[last.startIndex + j, yIndexNot] + 1; newGrid.dirtySquares.Add(new Vector2Int(last.startIndex + j, yIndex)); } } else { int xIndex = !last.side ? 0 : FlowGrid.gridResolution - 1; int xIndexNot = last.side ? 0 : FlowGrid.gridResolution - 1; for (int j = 0; j < last.size; j++) { newGrid.integrationField[xIndex, last.startIndex + j] = lastGrid.integrationField[xIndexNot, last.startIndex + j] + 1; newGrid.dirtySquares.Add(new Vector2Int(xIndex, last.startIndex + j)); } } newGrid.compute(); if (last.isHorizontal) { int yIndex = !last.side ? 0 : FlowGrid.gridResolution - 1; for (int j = 0; j < last.size; j++) { newGrid.directionField[last.startIndex + j, yIndex] = last.side ? 4 : 0; } } else { int xIndex = !last.side ? 0 : FlowGrid.gridResolution - 1; for (int j = 0; j < last.size; j++) { newGrid.directionField[xIndex, last.startIndex + j] = last.side ? 2 : 6; } } if (!hasVisited) { request.chunkSteps.Add(new Vector2Int(current.gridX, current.gridY), newGrid); } else { request.chunkSteps[new Vector2Int(current.gridX, current.gridY)] = newGrid; } lastGrid = newGrid; } } return(request); }
public PortalGraph generateGraph() { PortalGraph graph = new PortalGraph(mapSize); for (int x = 0; x < 2 * mapSize - 2; x++) { bool horiz = x % 2 == 0; for (int y = 0; y < mapSize - 1 + (horiz ? -1 : 0); y++) { bool sideA; bool sideB; if (horiz)//TODO simplify these lines of code { sideA = FlowFieldHandler.grid.getBuilding((x / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()), (y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution - 1) * FlowFieldHandler.grid.getSpacing()) == -1; sideB = FlowFieldHandler.grid.getBuilding((x / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()), (y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution) * FlowFieldHandler.grid.getSpacing()) == -1; } else { sideA = FlowFieldHandler.grid.getBuilding(((x - 1) / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution - 1) * FlowFieldHandler.grid.getSpacing(), y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) == -1; sideB = FlowFieldHandler.grid.getBuilding(((x - 1) / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution) * FlowFieldHandler.grid.getSpacing(), y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) == -1; } bool foundPortal = sideA && sideB; int startIndex = -1; int size = -1; if (foundPortal) { startIndex = 0; size = 1; } for (int i = 1; i < FlowGrid.gridResolution; i++) { if (horiz) { sideA = FlowFieldHandler.grid.getBuilding((x / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + i * FlowFieldHandler.grid.getSpacing(), (y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution - 1) * FlowFieldHandler.grid.getSpacing()) == -1; sideB = FlowFieldHandler.grid.getBuilding((x / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + i * FlowFieldHandler.grid.getSpacing(), (y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution) * FlowFieldHandler.grid.getSpacing()) == -1; //Debug.Log("Horiz: " + new Vector2((x / 2 * FlowGrid.gridResolution * 10) + i * 10, (y * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution - 1) * 10)); //Debug.Log(FlowField.grid.getBuilding((x / 2 * FlowGrid.gridResolution * 10) + i * 10, (y * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution - 1) * 10)); //Debug.Log(FlowField.grid.getBuilding((x / 2 * FlowGrid.gridResolution * 10) + i * 10, (y * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution) * 10)); } else { sideA = FlowFieldHandler.grid.getBuilding(((x - 1) / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution - 1) * FlowFieldHandler.grid.getSpacing(), y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing() + i * FlowFieldHandler.grid.getSpacing()) == -1; sideB = FlowFieldHandler.grid.getBuilding(((x - 1) / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution) * FlowFieldHandler.grid.getSpacing(), y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing() + i * FlowFieldHandler.grid.getSpacing()) == -1; //Debug.Log("Vert: " + new Vector2((x / 2 * FlowGrid.gridResolution * 10), (y * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution - 1) * 10 + i * 10)); //Debug.Log(FlowField.grid.getBuilding((x / 2 * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution - 1) * 10, (y * FlowGrid.gridResolution * 10 + i * 10))); //Debug.Log(FlowField.grid.getBuilding((x / 2 * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution) * 10, (y * FlowGrid.gridResolution * 10 + i * 10))); } if (sideA && sideB) { if (foundPortal) { size++; } else { foundPortal = true; startIndex = i; size = 1; } } else { if (foundPortal) { foundPortal = false; graph.AddPortal(x, y, size, startIndex); } } } if (foundPortal) { graph.AddPortal(x, y, size, startIndex); } } } for (int x = 0; x < mapSize; x++) { for (int y = 0; y < mapSize; y++) { List <int> portalIndices = graph.associatedNodes[x, y]; for (int i = 0; i < portalIndices.Count; i++) { int startX; int startY; int startPortalIndex = portalIndices[i]; PortalGraph.PortalNode start = graph.nodes[startPortalIndex]; bool isHoriz = start.isHorizontal; if (isHoriz) { startX = start.startIndex; startY = (start.side ? 0 : FlowGrid.gridResolution - 1); } else { startY = start.startIndex; startX = (start.side ? 0 : FlowGrid.gridResolution - 1); } for (int j = i + 1; j < portalIndices.Count; j++) { int targetX; int targetY; int targetPortalIndex = portalIndices[j]; PortalGraph.PortalNode target = graph.nodes[targetPortalIndex]; isHoriz = target.isHorizontal; if (isHoriz) { targetX = target.startIndex; targetY = (target.side ? 0 : FlowGrid.gridResolution - 1); } else { targetY = target.startIndex; targetX = (target.side ? 0 : FlowGrid.gridResolution - 1); } bool foundPath = pathfinding.calculatePath(mapData[x, y], mapData[x, y].AStarGrid[startX, startY], mapData[x, y].AStarGrid[targetX, targetY]); if (foundPath) { graph.Connect(startPortalIndex, targetPortalIndex); } } } } } return(graph); }