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); } }
// 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); }