Exemplo n.º 1
0
    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);
                    }
                }
            }
        }
    }
Exemplo n.º 2
0
    //走廊,过道寻路生成
    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
                    }
                }
            }
        }
    }