void PathfindHallways() { DungeonPathfinder3D aStar = new DungeonPathfinder3D(size); foreach (var edge in selectedEdges) { var startRoom = (edge.U as Vertex <Room>).Item; var endRoom = (edge.V as Vertex <Room>).Item; var startPosf = startRoom.bounds.center; var endPosf = endRoom.bounds.center; var startPos = new Vector3Int((int)startPosf.x, (int)startPosf.y, (int)startPosf.z); var endPos = new Vector3Int((int)endPosf.x, (int)endPosf.y, (int)endPosf.z); var path = aStar.FindPath(startPos, endPos, (DungeonPathfinder3D.Node a, DungeonPathfinder3D.Node b) => { var pathCost = new DungeonPathfinder3D.PathCost(); var delta = b.Position - a.Position; if (delta.y == 0) { //flat hallway pathCost.cost = Vector3Int.Distance(b.Position, endPos); //heuristic if (grid[b.Position] == CellType.Stairs) { return(pathCost); } else if (grid[b.Position] == CellType.Room) { pathCost.cost += 5; } else if (grid[b.Position] == CellType.None) { pathCost.cost += 1; } pathCost.traversable = true; } else { //staircase if ((grid[a.Position] != CellType.None && grid[a.Position] != CellType.Hallway) || (grid[b.Position] != CellType.None && grid[b.Position] != CellType.Hallway)) { return(pathCost); } pathCost.cost = 100 + Vector3Int.Distance(b.Position, endPos); //base cost + heuristic int xDir = Mathf.Clamp(delta.x, -1, 1); int zDir = Mathf.Clamp(delta.z, -1, 1); Vector3Int verticalOffset = new Vector3Int(0, delta.y, 0); Vector3Int horizontalOffset = new Vector3Int(xDir, 0, zDir); if (!grid.InBounds(a.Position + verticalOffset) || !grid.InBounds(a.Position + horizontalOffset) || !grid.InBounds(a.Position + verticalOffset + horizontalOffset)) { return(pathCost); } if (grid[a.Position + horizontalOffset] != CellType.None || grid[a.Position + horizontalOffset * 2] != CellType.None || grid[a.Position + verticalOffset + horizontalOffset] != CellType.None || grid[a.Position + verticalOffset + horizontalOffset * 2] != CellType.None) { return(pathCost); } pathCost.traversable = true; pathCost.isStairs = true; } return(pathCost); }); if (path != null) { for (int i = 0; i < path.Count; i++) { var current = path[i]; if (grid[current] == CellType.None) { grid[current] = CellType.Hallway; } if (i > 0) { var prev = path[i - 1]; var delta = current - prev; if (delta.y != 0) { int xDir = Mathf.Clamp(delta.x, -1, 1); int zDir = Mathf.Clamp(delta.z, -1, 1); Vector3Int verticalOffset = new Vector3Int(0, delta.y, 0); Vector3Int horizontalOffset = new Vector3Int(xDir, 0, zDir); grid[prev + horizontalOffset] = CellType.Stairs; grid[prev + horizontalOffset * 2] = CellType.Stairs; grid[prev + verticalOffset + horizontalOffset] = CellType.Stairs; grid[prev + verticalOffset + horizontalOffset * 2] = CellType.Stairs; PlaceStairs(prev + horizontalOffset); PlaceStairs(prev + horizontalOffset * 2); PlaceStairs(prev + verticalOffset + horizontalOffset); PlaceStairs(prev + verticalOffset + horizontalOffset * 2); } Debug.DrawLine(prev + new Vector3(0.5f, 0.5f, 0.5f), current + new Vector3(0.5f, 0.5f, 0.5f), Color.blue, 100, false); } } foreach (var pos in path) { if (grid[pos] == CellType.Hallway) { PlaceHallway(pos); } } } } }
//走廊,过道寻路生成 private void PathfindHallways() { DungeonPathfinder3D aStar = new DungeonPathfinder3D(size); foreach (var edge in selectedEdges) { var startRoom = (edge.U as Vertex <Room>).Item; var endRoom = (edge.V as Vertex <Room>).Item; var startPosf = startRoom.bounds.center; var endPosf = endRoom.bounds.center; var startPos = new Vector3Int((int)startPosf.x, (int)startPosf.y, (int)startPosf.z); var endPos = new Vector3Int((int)endPosf.x, (int)endPosf.y, (int)endPosf.z); var path = aStar.FindPath(startPos, endPos, (DungeonPathfinder3D.Node a, DungeonPathfinder3D.Node b) => { var pathCost = new DungeonPathfinder3D.PathCost(); var delta = b.Position - a.Position; if (delta.y == 0) { //flat hallway pathCost.cost = Vector3Int.Distance(b.Position, endPos); //heuristic if (grid[b.Position] == CellType.Stairs) { return(pathCost); } else if (grid[b.Position] == CellType.Room) { pathCost.cost += 5; } else if (grid[b.Position] == CellType.None) { pathCost.cost += 1; } pathCost.traversable = true; } else { //staircase if ((grid[a.Position] != CellType.None && grid[a.Position] != CellType.Hallway) || (grid[b.Position] != CellType.None && grid[b.Position] != CellType.Hallway)) { return(pathCost); } pathCost.cost = 100 + Vector3Int.Distance(b.Position, endPos); //base cost + heuristic int xDir = Mathf.Clamp(delta.x, -1, 1); int zDir = Mathf.Clamp(delta.z, -1, 1); Vector3Int verticalOffset = new Vector3Int(0, delta.y, 0); Vector3Int horizontalOffset = new Vector3Int(xDir, 0, zDir); if (!grid.InBounds(a.Position + verticalOffset) || !grid.InBounds(a.Position + horizontalOffset) || !grid.InBounds(a.Position + verticalOffset + horizontalOffset)) { return(pathCost); } if (grid[a.Position + horizontalOffset] != CellType.None || grid[a.Position + horizontalOffset * 2] != CellType.None || grid[a.Position + verticalOffset + horizontalOffset] != CellType.None || grid[a.Position + verticalOffset + horizontalOffset * 2] != CellType.None) { return(pathCost); } pathCost.traversable = true; pathCost.isStairs = true; } return(pathCost); }); if (path != null) { for (int i = 0; i < path.Count; i++) { var current = path[i]; if (grid[current] == CellType.None) { grid[current] = CellType.Hallway; } if (i > 0) { var prev = path[i - 1]; //path有可能在循环中改变,未验证?? //add by csd createStairs(current, prev, true); //add end /* * var delta = current - prev; * * if (delta.y != 0) { * int xDir = Mathf.Clamp(delta.x, -1, 1); * int zDir = Mathf.Clamp(delta.z, -1, 1); * Vector3Int verticalOffset = new Vector3Int(0, delta.y, 0); * Vector3Int horizontalOffset = new Vector3Int(xDir, 0, zDir); * * grid[prev + horizontalOffset] = CellType.Stairs; * grid[prev + horizontalOffset * 2] = CellType.Stairs; * grid[prev + verticalOffset + horizontalOffset] = CellType.Stairs; * grid[prev + verticalOffset + horizontalOffset * 2] = CellType.Stairs; * * PlaceStairs(prev + horizontalOffset); * PlaceStairs(prev + horizontalOffset * 2); * PlaceStairs(prev + verticalOffset + horizontalOffset); * PlaceStairs(prev + verticalOffset + horizontalOffset * 2); * } * * Debug.DrawLine(prev + new Vector3(0.5f, 0.5f, 0.5f), current + new Vector3(0.5f, 0.5f, 0.5f), Color.blue, 100, false); */ pathVector tmpPath = new pathVector(); tmpPath.sourVector = prev; tmpPath.destVector = current; pathLst.Add(tmpPath); } } foreach (var pos in path) //两个房间之间的一条路径 { if (grid[pos] == CellType.Hallway) { PlaceHallway(pos); //add by csd begin bool isCreate = grid.getDataIsCreate(pos); if (isCreate == false) { //HallWay newHallWay = new HallWay(pos, new Vector3Int(1, 1, 1), planePrefab, wallPrefab, hallWayPlaceMaterial, placeGrid, roomIndex, mazeParent); GameObject newHallWayObj = new GameObject(); newHallWayObj.transform.SetParent(mazeParent.transform); newHallWayObj.name = "hallway" + pos.x.ToString() + "_" + pos.z.ToString() + "_" + pos.y.ToString(); HallWay newHallWay = newHallWayObj.AddComponent <HallWay>(); newHallWay.initDataHallWay(pos, new Vector3Int(1, 1, 1), planePrefab, wallPrefab, hallWayPlaceMaterial, placeGrid, roomIndex, newHallWayObj); /* * HallWay newHallWay = mazeParent.AddComponent<HallWay>(); * newHallWay.initData(pos, new Vector3Int(1, 1, 1), planePrefab, wallPrefab, hallWayPlaceMaterial, placeGrid, roomIndex, mazeParent); */ hallways.Add(newHallWay); grid.setGridDataObj(newHallWay, pos); roomIndex++; // grid.setDataIsCreate(pos,true); } //add end } } } } }