void Start()
    {
        instance = this;
        tempList = new List <Vector2>();
        for (int i = 0; i < 10; i++)
        {
            tempList.Add(RoomGenerationInCircle.getRandomPointInCircle(100, 1));
        }
        // tempList.Add(new Vector2(-123,73));
        // tempList.Add(new Vector2(108,-63));
        // tempList.Add(new Vector2(-107,-46));
        // tempList.Add(new Vector2(-39,-8));
        // tempList.Add(new Vector2(-54,110));
        triangles = Polygon2D.DelaunayTriangulation(tempList);

        // foreach (var item in triangles)
        // {
        //     Debug.DrawLine(item.pointA, item.pointB);
        //     Debug.DrawLine(item.pointA, item.pointC);
        //     Debug.DrawLine(item.pointC, item.pointB);
        // }
        // StartCoroutine(Draw());
    }
 private void Update()
 {
     foreach (var item in tempList)
     {
         Debug.DrawLine(item + Vector2.up, item + Vector2.down);
         Debug.DrawLine(item + Vector2.left, item + Vector2.right);
     }
     foreach (var item in triangles)
     {
         Debug.DrawLine(item.pointA, item.pointB);
         Debug.DrawLine(item.pointA, item.pointC);
         Debug.DrawLine(item.pointC, item.pointB);
     }
     if (Input.GetKeyDown("space"))
     {
         tempList.RemoveRange(0, tempList.Count);
         for (int i = 0; i < 10; i++)
         {
             tempList.Add(RoomGenerationInCircle.getRandomPointInCircle(100, 1));
         }
         triangles = Polygon2D.DelaunayTriangulation(tempList);
     }
 }
Beispiel #3
0
    // todo 尝试使用异步完成
    public IEnumerator GenerationRooms()
    {
        UnityEngine.Random.InitState(seed);
        int   currentFinishCount = 0;
        float roomAverage        = 0;

        //设置当前状态
        isGenerating = true;
        for (int i = 0; i < RoomCount; i++)
        {
            // todo 将tilesize设定成参数。
            // 生成房间初始位置
            Vector2 pos = getRandomPointInEllipse(GenerateRadius, GenerateRadius, 1);
            // Debug.Log("pos : " + pos);
            // 房间大小可以使用随机也可以使用预制的房间
            Vector2 size = getRandomSizeInCircle(RoomRadius, 2);
            // Debug.Log("size : " + size);
            roomAverage += size.Sum();
            // 根据大小和初始位置生成房间
            RoomForCircle temp = GenerationRoom(this.transform, pos, size, testSprtie);
            roomList.Add(temp);
            temp.transform.localScale = new Vector3(1, 1, 1);
            // 设置物体碰撞完成时的callback回调
            temp.rigidBody.onSimualtedFinishCallback += () => { currentFinishCount++; };
            //延迟
            yield return(new WaitForFixedUpdate());
        }
        // todo 可以自行调用来完成碰撞,减少随机性。可以通过随机来控制
        float timer = 0;

        while (timer < maxWaitTime && currentFinishCount < RoomCount)
        {
            yield return(new WaitForFixedUpdate());

            timer += Time.fixedDeltaTime;
        }
        // 获取主要房间
        roomAverage /= roomList.Count;
        mainRoomList = GetMainRoom(roomList, roomAverage * mainRoomThreshold);
        foreach (var room in mainRoomList)
        {
            // todo 可定制的主房间,使用代理
            DrawRoomInTilemap(floorTilemap, wallTilemap, floorTile, wallTile, room.transform.position.ToVector2(), room.size);
        }
        // 通过三角剖分获取主要房间之间的联通路
        List <Vector2>  mainRoomPos = mainRoomList.ToPosition();
        List <Triangle> triangles   = Polygon2D.DelaunayTriangulation(mainRoomPos);

        roadList = triangles.GetEdges();
        foreach (var r in roadList)
        {
            Debug.DrawLine(mainRoomPos[r.indexA], mainRoomPos[r.indexB], Color.green, 1f);
        }
        // 使用最小生成树算法生成真实路径,
        List <Edge> mainRoadList = GetMainRoad(roadList, mainRoomPos);

        foreach (var r in mainRoadList)
        {
            Debug.DrawLine(mainRoomPos[r.indexA], mainRoomPos[r.indexB], Color.red, 1f);
        }
        // 算法思路:
        // 将两个房间确定一个矩形范围,在范围中确定一个点,用作折现点。
        foreach (var road in mainRoadList)
        {
            RoomForCircle roomA = mainRoomList[road.indexA];
            RoomForCircle roomB = mainRoomList[road.indexB];
            // todo 可定制的path 使用代理
            // 获取房间之间的路径点, 获取的路径点头和尾分别是房间A和房间B的门口
            Vector2[]  PathPoints = GetPathsBetweenRoom(roomA, roomB);
            GameObject pA         = new GameObject("point0" + roomA.GetHashCode());
            pA.transform.parent   = this.gameObject.transform;
            pA.transform.position = PathPoints[0];
            for (int i = 0; i < PathPoints.Length - 1; i++)
            {
                Debug.DrawLine(PathPoints[i] + new Vector2(0.5f, 0.5f), PathPoints[i + 1] + new Vector2(0.5f, 0.5f), Color.white, 1f);
                GameObject temp = new GameObject("point" + i);
                temp.transform.parent   = pA.transform;
                temp.transform.position = PathPoints[i + 1] + new Vector2(0.5f, 0.5f);
            }

            // 对连线之间的房间进行选取,映射到tilemap中
            // todo 可选的判断方法,间隔一个距离使用raycast 进行判断,减少性能消耗。
            // BUG 房间内有概率出现走廊。
            // BUG side房间的判断有时候有问题
            for (int i = 0; i < PathPoints.Length - 1; i++)
            {
                RaycastHit2D[] result = new RaycastHit2D[mainRoadList.Count];// todo 这里的数量可以动态调整
                int            n      = Physics2D.RaycastNonAlloc(
                    PathPoints[i] + new Vector2(0.5f, 0.5f),
                    (PathPoints[i + 1] - PathPoints[i]).normalized,
                    result, Vector2.Distance(PathPoints[i + 1], PathPoints[i]));
                for (int j = 0; j < n; j++)
                {
                    RaycastHit2D  temp = result[j];
                    RoomForCircle room = temp.collider.gameObject.GetComponent <RoomForCircle>();
                    if (room.roomType == RoomType.NoneRoom)
                    {
                        room.roomType     = RoomType.SideRoom;
                        room.sprite.color = Color.red;
                        // todo 可定制的side房间,使用代理
                        DrawRoomInTilemap(floorTilemap, wallTilemap, floorTile, wallTile, room.transform.position, room.size);
                    }
                }
            }
            DrawHallwayInTilemap(floorTilemap, wallTilemap, floorTile, wallTile, PathPoints);
        }



        isGenerating = false;
        this.gameObject.SetActive(false);
    }