示例#1
0
        public List <ISpace> GenerateNext()
        {
            List <ISpace> ways          = new List <ISpace>();
            int           hallHalfWidth = 2;

            for (int i = 0; i < 4; i++)
            {
                if (hallWays[i] != null)
                {
                    continue;                                           // Is already used
                }
                if (UnityEngine.Random.value < 0.2 * depth)
                {
                    continue;                                           // RNG sais no
                }
                Vector2Int startPos = Vector2Int.zero;
                switch ((Cardinal)i)
                {
                case Cardinal.NORTH: startPos = new Vector2Int(box.xMin + UnityEngine.Random.Range(hallHalfWidth + 1, box.width - hallHalfWidth - 2), box.yMax); break;

                case Cardinal.EAST: startPos = new Vector2Int(box.xMax, box.yMin + UnityEngine.Random.Range(hallHalfWidth + 1, box.height - hallHalfWidth - 2)); break;

                case Cardinal.SOUTH: startPos = new Vector2Int(box.xMin + UnityEngine.Random.Range(hallHalfWidth + 1, box.width - hallHalfWidth - 2), box.yMin); break;

                case Cardinal.WEST: startPos = new Vector2Int(box.xMin, box.yMin + UnityEngine.Random.Range(hallHalfWidth + 1, box.height - hallHalfWidth - 2)); break;

                default: throw new Exception();
                }
                hallWays[i] = HallWay.Generate(this, (Cardinal)i, startPos, hallHalfWidth, level);
                ways.Add(hallWays[i]);
            }
            return(ways);
        }
示例#2
0
 //生成过道
 public void createHallWayLst()
 {
     for (int i = 0; i < hallways.Count; i++)
     {
         HallWay tmpHallWay = hallways[i];
         tmpHallWay.makeAllPlane();
         tmpHallWay.makeAllWall();
         //tmpHallWay.bounds.
         //PlaceHallway(pos);
     }
 }
示例#3
0
        public static PrisonCell Generate(HallWay previous, Cardinal buildingDirection, Vector2Int startPos, int level)
        {
            PrisonCell cell = new PrisonCell()
            {
                parent    = previous,
                position  = startPos,
                direction = buildingDirection,
                depth     = previous.Depth,
                width     = UnityEngine.Random.Range(3, 5),
                height    = UnityEngine.Random.Range(2, 5)
            };

            return(cell);
        }
示例#4
0
        public static Room Generate(HallWay previous, Cardinal buildingDirection, Vector2Int startPos, int level)
        {
            Room room = new Room();

            room.level = level;
            if (previous == null)
            {
                room.box   = new RectInt(-20, -20, 40, 40);
                room.depth = 0;
            }
            else
            {
                room.hallWays[((int)buildingDirection + 2) % 4] = previous;
                int width  = UnityEngine.Random.Range(20, 50);
                int height = UnityEngine.Random.Range(20, 50);
                switch (buildingDirection)
                {
                case Cardinal.NORTH:
                    int startpoint = UnityEngine.Random.Range(2, width - 3);
                    room.box = new RectInt(startPos.x - startpoint, startPos.y, width, height);
                    break;

                case Cardinal.SOUTH:
                    startpoint = UnityEngine.Random.Range(2, width - 3);
                    room.box   = new RectInt(startPos.x - startpoint, startPos.y - height, width, height);
                    break;

                case Cardinal.EAST:
                    startpoint = UnityEngine.Random.Range(2, height - 3);
                    room.box   = new RectInt(startPos.x, startPos.y - startpoint, width, height);
                    break;

                case Cardinal.WEST:
                    startpoint = UnityEngine.Random.Range(2, height - 3);
                    room.box   = new RectInt(startPos.x - width, startPos.y - startpoint, width, height);
                    break;
                }
                room.depth = previous.Depth;
            }
            return(room);
        }
示例#5
0
        public static HallWay Generate(Room previous, Cardinal buildingDirection, Vector2Int startPos, float halfWidth, int level)
        {
            HallWay hallWay = new HallWay();

            hallWay.rooms[0]   = previous;
            hallWay.startPoint = startPos;
            int        length1 = UnityEngine.Random.Range(15, 60);
            int        length2 = UnityEngine.Random.Range(10, 70);
            Vector2Int dir     = GetDir(buildingDirection);

            hallWay.wayPoint  = startPos + dir * length1;
            hallWay.turnRight = UnityEngine.Random.value > 0.5;
            Vector2Int nexDir = GetDir((Cardinal)(((int)buildingDirection + (hallWay.turnRight ? 1 : -1)) % 4));

            hallWay.endPoint  = hallWay.wayPoint + nexDir * length2;
            hallWay.halfWidth = 2;
            hallWay.depth     = previous.Depth + 1;
            hallWay.level     = level;
            hallWay.direction = buildingDirection;
            return(hallWay);
        }
示例#6
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);
                            hallways.Add(newHallWay);
                            grid.setGridDataObj(newHallWay, pos);

                            roomIndex++;
                            // grid.setDataIsCreate(pos,true);
                        }
                        //add end
                    }
                }
            }
        }
    }
示例#7
0
 public void AddHallWay(HallWay hallway)
 {
     hallways.Add(hallway);
 }
示例#8
0
    IEnumerator Create()
    {
        #region Create Random Size & Pos Rooms
        int counter    = 0;
        int roomAmount = 25;
        int widthSum   = 0;
        int heightSum  = 0;
        while (counter < roomAmount)
        {
            Room room = CreateRandRoom();
            room.name = counter.ToString();
            rooms.Add(room);
            counter++;

            // sum width/height
            widthSum  += room.Width;
            heightSum += room.Height;

            yield return(new WaitForSeconds(0.05f));
        }
        #endregion

        #region Remove Small Rooms
        float widthMean  = widthSum / roomAmount;
        float heightMean = heightSum / roomAmount;

        yield return(new WaitForSeconds(4));

        for (int i = 0; i < rooms.Count; i++)
        {
            //rooms[i].RemovePhysics();
            rooms [i].ResetRect();

            if (rooms [i].Width < widthMean || rooms [i].Height < heightMean)
            {
                Destroy(rooms [i].gameObject);
                rooms.Remove(rooms [i]);
                i--;
            }
        }
        yield return(new WaitForSeconds(0.5f));

        #endregion

        #region  Create room connection using DelaunayTriangles
        _points = new List <Vector2> ();
        for (int i = 0; i < rooms.Count; i++)
        {
            _points.Add(rooms [i].Position);
        }
        Rect rect = GetMinRect(rooms);

        Voronoi v = new Voronoi(_points, null, rect);
        _edges                 = v.VoronoiDiagram();
        _spanningTree          = v.SpanningTree(KruskalType.MINIMUM);
        _delaunayTriangulation = v.DelaunayTriangulation();
        #endregion

        #region Extra Loop Connection
        int maxExtraPathAmt = (int)(_delaunayTriangulation.Count * 0.1f);
        int rand            = Random.Range(1, maxExtraPathAmt);
        Debug.Log(rand);

        while (rand > 0)
        {
            int randIndex = Random.Range(0, _delaunayTriangulation.Count);

            if (_spanningTree.Contains(_delaunayTriangulation [randIndex]))
            {
                continue;
            }
            else
            {
                _spanningTree.Add(_delaunayTriangulation [randIndex]);
                rand--;
            }
        }
        yield return(new WaitForSeconds(0.5f));

        #endregion

        #region Create HallWays
        for (int i = 0; i < _spanningTree.Count; i++)
        {
            yield return(new WaitForSeconds(0.2f));

            Room room0 = GetRoomFromPos(_spanningTree [i].p0);
            Room room1 = GetRoomFromPos(_spanningTree [i].p1);

            Debug.Log("Creating Hallway Between " + room0.name + "  " + room1.name);

            float xDistance = Mathf.Abs(room0.Position.x - room1.Position.x);
            float yDistance = Mathf.Abs(room0.Position.y - room1.Position.y);

            float xMidPointDistance = xDistance / 2;
            float yMidPointDistance = yDistance / 2;

            #region Close in X-Axis
            // mid x point is inside of both rects
            if (room0.Position.x + xMidPointDistance < room0.rectMaxX &&         // removed equal sign ==> 避免房间刚好快要重叠,防止做路径时麻烦,因为路径瓦片可能会刚好在网格线上
                room1.Position.x + xMidPointDistance < room1.rectMaxX)
            {
                Vector2 startPoint = Vector2.zero;
                Vector2 endPoint   = Vector2.zero;

                // room0 above room1
                if (room0.Position.y >= room1.Position.y)
                {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x)
                    {
                        startPoint.Set(room0.Position.x + xMidPointDistance, room0.rectMinY);
                        endPoint.Set(room1.Position.x - xMidPointDistance, room1.rectMaxY);
                    }
                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x)
                    {
                        startPoint.Set(room0.Position.x - xMidPointDistance, room0.rectMinY);
                        endPoint.Set(room1.Position.x + xMidPointDistance, room1.rectMaxY);
                    }
                }

                // room1 above room0
                else if (room0.Position.y < room1.Position.y)
                {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x)
                    {
                        startPoint.Set(room0.Position.x + xMidPointDistance, room0.rectMaxY);
                        endPoint.Set(room1.Position.x - xMidPointDistance, room1.rectMinY);
                    }
                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x)
                    {
                        startPoint.Set(room0.Position.x - xMidPointDistance, room0.rectMaxY);
                        endPoint.Set(room1.Position.x + xMidPointDistance, room1.rectMinY);
                    }
                }

                #endregion

                // create vertical line
                HallWay hallway = new HallWay(startPoint, endPoint, room0, room1);
                _hallways.Add(hallway);
                room0.AddHallWay(hallway);
                Debug.Log("##CloseXAxis created hallway from " + startPoint + " to " + endPoint + " between " + room0.name + "  " + room1.name);
            }

            #region Close In Y-Axis
            // mid y point is inside of both rects
            else if (room0.Position.y + yMidPointDistance < room0.rectMaxY &&
                     room1.Position.y + yMidPointDistance < room1.rectMaxY)
            {
                Vector2 startPoint = Vector2.zero;
                Vector2 endPoint   = Vector2.zero;

                // room0 above room1
                if (room0.Position.y >= room1.Position.y)
                {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x)
                    {
                        startPoint.Set(room0.rectMaxX, room0.Position.y - yMidPointDistance);
                        endPoint.Set(room1.rectMinX, room1.Position.y + yMidPointDistance);
                    }
                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x)
                    {
                        startPoint.Set(room0.rectMinX, room0.Position.y - yMidPointDistance);
                        endPoint.Set(room1.rectMaxX, room1.Position.y + yMidPointDistance);
                    }
                }

                // room1 above room0
                else if (room0.Position.y < room1.Position.y)
                {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x)
                    {
                        startPoint.Set(room0.rectMaxX, room0.Position.y + yMidPointDistance);
                        endPoint.Set(room1.rectMinX, room1.Position.y - yMidPointDistance);
                    }
                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x)
                    {
                        startPoint.Set(room0.rectMinX, room0.Position.y + yMidPointDistance);
                        endPoint.Set(room1.rectMaxX, room1.Position.y - yMidPointDistance);
                    }
                }

                // create vertical line
                HallWay hallway = new HallWay(startPoint, endPoint, room0, room1);
                _hallways.Add(hallway);
                room0.AddHallWay(hallway);

                Debug.Log("##CloseYAxis created hallway from " + startPoint + " to " + endPoint + " between " + room0.name + "  " + room1.name);
            }
            #endregion

            #region Far In Both Axis
            // create L shape hall way
            else
            {
                Vector2 startPoint = Vector2.zero;
                Vector2 turnPoint  = Vector2.zero;
                Vector2 endPoint   = Vector2.zero;

                // room0 above room1
                if (room0.Position.y >= room1.Position.y)
                {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x)
                    {
                        startPoint.Set(room0.rectMaxX, room0.Position.y);
                        turnPoint.Set(room0.Position.x + xDistance, room0.Position.y);
                        endPoint.Set(room1.Position.x, room1.rectMaxY);

                        #region Check If Line Collider With Other Room
                        if (LineHasCollision(startPoint, turnPoint, room0.Collider)
                            ||
                            LineHasCollision(turnPoint, endPoint, room1.Collider))
                        {
                            // go other way
                            startPoint.Set(room0.Position.x, room0.rectMinY);
                            turnPoint.Set(room0.Position.x, room0.Position.y - yDistance);
                            endPoint.Set(room1.rectMinX, room1.Position.y);
                            Debug.Log("go other way");
                        }

                        // still has collision, delete this segment from spanning tree
                        if (LineHasCollision(startPoint, turnPoint, room0.Collider)
                            ||
                            LineHasCollision(turnPoint, endPoint, room1.Collider))
                        {
                            Debug.Log("still collision, remove path");

                            _spanningTree.RemoveAt(i);
                            i--;
                            continue;
                        }
                        #endregion
                    }

                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x)
                    {
                        startPoint.Set(room0.rectMinX, room0.Position.y);
                        turnPoint.Set(room0.Position.x - xDistance, room0.Position.y);
                        endPoint.Set(room1.Position.x, room1.rectMaxY);

                        #region Check If Line Collider With Other Room
                        if (LineHasCollision(startPoint, turnPoint, room0.Collider)
                            ||
                            LineHasCollision(turnPoint, endPoint, room1.Collider))
                        {
                            // go other way
                            startPoint.Set(room0.Position.x, room0.rectMinY);
                            turnPoint.Set(room0.Position.x, room0.Position.y - yDistance);
                            endPoint.Set(room1.rectMaxX, room1.Position.y);

                            Debug.Log("go other way");
                        }

                        // still has collision, delete this segment from spanning tree
                        if (LineHasCollision(startPoint, turnPoint, room0.Collider)
                            ||
                            LineHasCollision(turnPoint, endPoint, room1.Collider))
                        {
                            Debug.Log("still collison, delete path");

                            _spanningTree.RemoveAt(i);
                            i--;
                            continue;
                        }
                        #endregion
                    }
                }

                // room1 above room0
                else if (room0.Position.y < room1.Position.y)
                {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x)
                    {
                        startPoint.Set(room0.Position.x, room0.rectMaxY);
                        turnPoint.Set(room0.Position.x, room0.Position.y + yDistance);
                        endPoint.Set(room1.rectMinX, room1.Position.y);

                        #region Check If Line Collider With Other Room
                        if (LineHasCollision(startPoint, turnPoint, room0.Collider)
                            ||
                            LineHasCollision(turnPoint, endPoint, room1.Collider))
                        {
                            // go other way
                            startPoint.Set(room0.rectMaxX, room0.Position.y);
                            turnPoint.Set(room0.Position.x + xDistance, room0.Position.y);
                            endPoint.Set(room1.Position.x, room1.rectMinY);

                            Debug.Log("go other way");
                        }

                        // still has collision, delete this segment from spanning tree
                        if (LineHasCollision(startPoint, turnPoint, room0.Collider)
                            ||
                            LineHasCollision(turnPoint, endPoint, room1.Collider))
                        {
                            Debug.Log("still collision, delete path");
                            _spanningTree.RemoveAt(i);
                            i--;
                            continue;
                        }
                        #endregion
                    }
                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x)
                    {
                        startPoint.Set(room1.rectMaxX, room1.Position.y);
                        turnPoint.Set(room1.Position.x + xDistance, room1.Position.y);
                        endPoint.Set(room0.Position.x, room0.rectMaxY);

                        #region Check If Line Collider With Other Room
                        if (LineHasCollision(startPoint, turnPoint, room1.Collider)
                            ||
                            LineHasCollision(turnPoint, endPoint, room0.Collider))
                        {
                            // go other way
                            startPoint.Set(room1.Position.x, room1.rectMinY);
                            turnPoint.Set(room1.Position.x, room1.Position.y - yDistance);
                            endPoint.Set(room0.rectMinX, room0.Position.y);

                            Debug.Log("go other way");
                        }

                        // still has collision, delete this segment from spanning tree
                        if (LineHasCollision(startPoint, turnPoint, room1.Collider)
                            ||
                            LineHasCollision(turnPoint, endPoint, room0.Collider))
                        {
                            Debug.Log("still collision, delete path");
                            _spanningTree.RemoveAt(i);
                            i--;
                            continue;
                        }
                        #endregion
                    }
                }

                // create vertical line
                LHallWay hallway = new LHallWay(startPoint, turnPoint, endPoint, room0, room1);
                _hallways.Add(hallway);
                room0.AddHallWay(hallway);

                Debug.Log("##Lshape created hallway from " + startPoint + " to " + turnPoint + " to " + endPoint + " between " + room0.name + "  " + room1.name);
            }
            #endregion
        }

        #endregion

        #region Remove Physics
        for (int i = 0; i < rooms.Count; i++)
        {
            rooms [i].RemovePhysics();
        }
        #endregion

        #region Create Tiles
        for (int i = 0; i < rooms.Count; i++)
        {
            rooms [i].Fill();
            yield return(new WaitForSeconds(0.2f));
        }
        //for (int i = 0; i < _hallways.Count; i++) {
        //	_hallways [i].Fill ();
        //	yield return new WaitForSeconds (0.2f);
        //}
        #endregion
    }
示例#9
0
 public void AddHallWay(HallWay hallway)
 {
     hallways.Add (hallway);
 }
    IEnumerator Create()
    {
        #region Create Random Size & Pos Rooms
        int counter = 0;
        int roomAmount = 25;
        int widthSum = 0;
        int heightSum = 0;
        while (counter < roomAmount) {
            Room room = CreateRandRoom ();
            room.name = counter.ToString ();
            rooms.Add (room);
            counter++;

            // sum width/height
            widthSum += room.Width;
            heightSum += room.Height;

            yield return new WaitForSeconds (0.05f);
        }
        #endregion

        #region Remove Small Rooms
        float widthMean = widthSum / roomAmount;
        float heightMean = heightSum / roomAmount;

        yield return new WaitForSeconds (4);
        for (int i = 0; i < rooms.Count; i++) {
            //rooms[i].RemovePhysics();
            rooms [i].ResetRect ();

            if (rooms [i].Width < widthMean || rooms [i].Height < heightMean) {
                Destroy (rooms [i].gameObject);
                rooms.Remove (rooms [i]);
                i--;
            }
        }
        yield return new WaitForSeconds (0.5f);
        #endregion

        #region  Create room connection using DelaunayTriangles
        _points = new List<Vector2> ();
        for (int i = 0; i < rooms.Count; i++)
            _points.Add (rooms [i].Position);
        Rect rect = GetMinRect (rooms);

        Voronoi v = new Voronoi (_points, null, rect);
        _edges = v.VoronoiDiagram ();
        _spanningTree = v.SpanningTree (KruskalType.MINIMUM);
        _delaunayTriangulation = v.DelaunayTriangulation ();
        #endregion

        #region Extra Loop Connection
        int maxExtraPathAmt = (int)(_delaunayTriangulation.Count * 0.1f);
        int rand = Random.Range (1, maxExtraPathAmt);
        Debug.Log (rand);

        while (rand > 0) {
            int randIndex = Random.Range (0, _delaunayTriangulation.Count);

            if (_spanningTree.Contains (_delaunayTriangulation [randIndex]))
                continue;
            else {
                _spanningTree.Add (_delaunayTriangulation [randIndex]);
                rand--;
            }
        }
        yield return new WaitForSeconds (0.5f);
        #endregion

        #region Create HallWays
        for (int i = 0; i < _spanningTree.Count; i++) {
            yield return new WaitForSeconds (0.2f);
            Room room0 = GetRoomFromPos (_spanningTree [i].p0);
            Room room1 = GetRoomFromPos (_spanningTree [i].p1);

            Debug.Log ("Creating Hallway Between " + room0.name + "  " + room1.name);

            float xDistance = Mathf.Abs (room0.Position.x - room1.Position.x);
            float yDistance = Mathf.Abs (room0.Position.y - room1.Position.y);

            float xMidPointDistance = xDistance / 2;
            float yMidPointDistance = yDistance / 2;

            #region Close in X-Axis
            // mid x point is inside of both rects
            if (room0.Position.x + xMidPointDistance < room0.rectMaxX// removed equal sign ==> 避免房间刚好快要重叠,防止做路径时麻烦,因为路径瓦片可能会刚好在网格线上
                         && room1.Position.x + xMidPointDistance < room1.rectMaxX) {
                Vector2 startPoint = Vector2.zero;
                Vector2 endPoint = Vector2.zero;

                // room0 above room1
                if (room0.Position.y >= room1.Position.y) {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x) {
                        startPoint.Set (room0.Position.x + xMidPointDistance, room0.rectMinY);
                        endPoint.Set (room1.Position.x - xMidPointDistance, room1.rectMaxY);
                    }
                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x) {
                        startPoint.Set (room0.Position.x - xMidPointDistance, room0.rectMinY);
                        endPoint.Set (room1.Position.x + xMidPointDistance, room1.rectMaxY);
                    }
                }

                // room1 above room0
                else if (room0.Position.y < room1.Position.y) {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x) {
                        startPoint.Set (room0.Position.x + xMidPointDistance, room0.rectMaxY);
                        endPoint.Set (room1.Position.x - xMidPointDistance, room1.rectMinY);
                    }
                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x) {
                        startPoint.Set (room0.Position.x - xMidPointDistance, room0.rectMaxY);
                        endPoint.Set (room1.Position.x + xMidPointDistance, room1.rectMinY);
                    }
                }

                #endregion

                // create vertical line
                HallWay hallway = new HallWay (startPoint, endPoint, room0, room1);
                _hallways.Add (hallway);
                room0.AddHallWay (hallway);
                Debug.Log ("##CloseXAxis created hallway from " + startPoint + " to " + endPoint + " between " + room0.name + "  " + room1.name);
            }

            #region Close In Y-Axis
            // mid y point is inside of both rects
            else if (room0.Position.y + yMidPointDistance < room0.rectMaxY
                              && room1.Position.y + yMidPointDistance < room1.rectMaxY) {
                Vector2 startPoint = Vector2.zero;
                Vector2 endPoint = Vector2.zero;

                // room0 above room1
                if (room0.Position.y >= room1.Position.y) {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x) {
                        startPoint.Set (room0.rectMaxX, room0.Position.y - yMidPointDistance);
                        endPoint.Set (room1.rectMinX, room1.Position.y + yMidPointDistance);
                    }
                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x) {
                        startPoint.Set (room0.rectMinX, room0.Position.y - yMidPointDistance);
                        endPoint.Set (room1.rectMaxX, room1.Position.y + yMidPointDistance);
                    }
                }

                // room1 above room0
                else if (room0.Position.y < room1.Position.y) {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x) {
                        startPoint.Set (room0.rectMaxX, room0.Position.y + yMidPointDistance);
                        endPoint.Set (room1.rectMinX, room1.Position.y - yMidPointDistance);
                    }
                    // room1 left to room0
                else if (room0.Position.x > room1.Position.x) {
                        startPoint.Set (room0.rectMinX, room0.Position.y + yMidPointDistance);
                        endPoint.Set (room1.rectMaxX, room1.Position.y - yMidPointDistance);
                    }
                }

                // create vertical line
                HallWay hallway = new HallWay (startPoint, endPoint, room0, room1);
                _hallways.Add (hallway);
                room0.AddHallWay (hallway);

                Debug.Log ("##CloseYAxis created hallway from " + startPoint + " to " + endPoint + " between " + room0.name + "  " + room1.name);
            }
            #endregion

            #region Far In Both Axis
            // create L shape hall way
            else {
                Vector2 startPoint = Vector2.zero;
                Vector2 turnPoint = Vector2.zero;
                Vector2 endPoint = Vector2.zero;

                // room0 above room1
                if (room0.Position.y >= room1.Position.y) {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x) {
                        startPoint.Set (room0.rectMaxX, room0.Position.y);
                        turnPoint.Set (room0.Position.x + xDistance, room0.Position.y);
                        endPoint.Set (room1.Position.x, room1.rectMaxY);

                        #region Check If Line Collider With Other Room
                        if (LineHasCollision (startPoint, turnPoint, room0.Collider)
                                              ||
                                              LineHasCollision (turnPoint, endPoint, room1.Collider)) {
                            // go other way
                            startPoint.Set (room0.Position.x, room0.rectMinY);
                            turnPoint.Set (room0.Position.x, room0.Position.y - yDistance);
                            endPoint.Set (room1.rectMinX, room1.Position.y);
                            Debug.Log ("go other way");
                        }

                        // still has collision, delete this segment from spanning tree
                        if (LineHasCollision (startPoint, turnPoint, room0.Collider)
                                              ||
                                              LineHasCollision (turnPoint, endPoint, room1.Collider)) {
                            Debug.Log ("still collision, remove path");

                            _spanningTree.RemoveAt (i);
                            i--;
                            continue;
                        }
                        #endregion
                    }

                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x) {
                        startPoint.Set (room0.rectMinX, room0.Position.y);
                        turnPoint.Set (room0.Position.x - xDistance, room0.Position.y);
                        endPoint.Set (room1.Position.x, room1.rectMaxY);

                        #region Check If Line Collider With Other Room
                        if (LineHasCollision (startPoint, turnPoint, room0.Collider)
                                              ||
                                              LineHasCollision (turnPoint, endPoint, room1.Collider)) {
                            // go other way
                            startPoint.Set (room0.Position.x, room0.rectMinY);
                            turnPoint.Set (room0.Position.x, room0.Position.y - yDistance);
                            endPoint.Set (room1.rectMaxX, room1.Position.y);

                            Debug.Log ("go other way");
                        }

                        // still has collision, delete this segment from spanning tree
                        if (LineHasCollision (startPoint, turnPoint, room0.Collider)
                                              ||
                                              LineHasCollision (turnPoint, endPoint, room1.Collider)) {
                            Debug.Log ("still collison, delete path");

                            _spanningTree.RemoveAt (i);
                            i--;
                            continue;
                        }
                        #endregion
                    }
                }

                // room1 above room0
                else if (room0.Position.y < room1.Position.y) {
                    // room0 left to room1
                    if (room0.Position.x <= room1.Position.x) {
                        startPoint.Set (room0.Position.x, room0.rectMaxY);
                        turnPoint.Set (room0.Position.x, room0.Position.y + yDistance);
                        endPoint.Set (room1.rectMinX, room1.Position.y);

                        #region Check If Line Collider With Other Room
                        if (LineHasCollision (startPoint, turnPoint, room0.Collider)
                                              ||
                                              LineHasCollision (turnPoint, endPoint, room1.Collider)) {
                            // go other way
                            startPoint.Set (room0.rectMaxX, room0.Position.y);
                            turnPoint.Set (room0.Position.x + xDistance, room0.Position.y);
                            endPoint.Set (room1.Position.x, room1.rectMinY);

                            Debug.Log ("go other way");
                        }

                        // still has collision, delete this segment from spanning tree
                        if (LineHasCollision (startPoint, turnPoint, room0.Collider)
                                              ||
                                              LineHasCollision (turnPoint, endPoint, room1.Collider)) {
                            Debug.Log ("still collision, delete path");
                            _spanningTree.RemoveAt (i);
                            i--;
                            continue;
                        }
                        #endregion
                    }
                    // room1 left to room0
                    else if (room0.Position.x > room1.Position.x) {
                        startPoint.Set (room1.rectMaxX, room1.Position.y);
                        turnPoint.Set (room1.Position.x + xDistance, room1.Position.y);
                        endPoint.Set (room0.Position.x, room0.rectMaxY);

                        #region Check If Line Collider With Other Room
                        if (LineHasCollision (startPoint, turnPoint, room1.Collider)
                            ||
                            LineHasCollision (turnPoint, endPoint, room0.Collider)) {
                            // go other way
                            startPoint.Set (room1.Position.x, room1.rectMinY);
                            turnPoint.Set (room1.Position.x, room1.Position.y - yDistance);
                            endPoint.Set (room0.rectMinX, room0.Position.y);

                            Debug.Log ("go other way");
                        }

                        // still has collision, delete this segment from spanning tree
                        if (LineHasCollision (startPoint, turnPoint, room1.Collider)
                            ||
                            LineHasCollision (turnPoint, endPoint, room0.Collider)) {
                            Debug.Log ("still collision, delete path");
                            _spanningTree.RemoveAt (i);
                            i--;
                            continue;
                        }
                        #endregion
                    }
                }

                // create vertical line
                LHallWay hallway = new LHallWay (startPoint, turnPoint, endPoint, room0, room1);
                _hallways.Add (hallway);
                room0.AddHallWay (hallway);

                Debug.Log ("##Lshape created hallway from " + startPoint + " to " + turnPoint + " to " + endPoint + " between " + room0.name + "  " + room1.name);
            }
            #endregion
        }

        #endregion

        #region Remove Physics
        for (int i = 0; i < rooms.Count; i++)
            rooms [i].RemovePhysics ();
        #endregion

        #region Create Tiles
        for (int i = 0; i < rooms.Count; i++) {
            rooms [i].Fill ();
            yield return new WaitForSeconds (0.2f);
        }
        //for (int i = 0; i < _hallways.Count; i++) {
        //	_hallways [i].Fill ();
        //	yield return new WaitForSeconds (0.2f);
        //}
        #endregion
    }