이 글에서는 이전 글에서 만든 방을 여러개 만들어서 어떻게 펼칠 것인가를 알아보겠다.
맵 자동 생성 (1)
맵 자동 생성에서 방을 어떻게 만들 것인가에 대해서 알아보겠다. 우선 방의 구조는 이렇다.이처럼 룸 자식오브젝트로 실제 오브젝트를 둔다. 이러한 구조는 방을 펼칠 때를 위한 구조이다. 씬
tpree.tistory.com
public void StartGenerateRoom();
이 함수를 누르면 정해진 개수만큼 방을 랜덤한 위치에 생성을 시킨다.
테스트를 위해 이 함수를 UI버튼에 연결했다.
[SerializeField]
int minRoom;
[SerializeField]
int maxRoom;
[SerializeField]
int roomCount;
[SerializeField]
float roomPadding;
public void StartGenerateRoom()
{
rigidbody2Ds.Clear();
for (int i = 0; i < roomCount; i++)
{
int x = Random.Range(-5, 5);
int y = Random.Range(-5, 5);
GenerateRoom(new Vector3(x, y, 0));
}
foreach (Rigidbody2D rb in rigidbody2Ds)
{
rb.bodyType = RigidbodyType2D.Dynamic;
}
StartCoroutine("RunSeparation");
}
내부 코드는 이렇다.
에디터에서 설정한 변수들, (min, maxRoom == 방의 크기), 방의 개수를 나타낸다.
이 변수를 기준으로 특정 범위안에 룸을 생성한다. 랜덤한 위치 (x,y) 를 건네주면
그 위치에 룸을 생성한다.
그러면 이것들을 어떻게 펼칠 것인가?
복잡한 알고리즘도 있지만, 우선은 물리엔진을 사용해보는 방법이 아주 간단해보였다.
방 크기의 콜라이더를 하나씩 생성하여, 물리 시뮬레이션을 돌리면 겹치지 않을 때까지 밀려나게 되고,
간단하게 방을 펼칠 수 있다.
이걸 위해서 방의 구조를
이렇게 만들었고 Room 에 콜라이더와 리지드바디를 추가한다.
그리고 벽 콜라이더와의 충돌방지를 위해 Room1 은 비활성화시켜놓는다.
StartCoroutine("RunSeparation");
펼치기 위한 코루틴함수이다.
IEnumerator RunSeparation()
{
Time.timeScale = 10f;
while (!AllRoomsAreSleeping())
yield return null;
Time.timeScale = 1f;
for(int i=0;i<rigidbody2Ds.Count;i++)
{
rigidbody2Ds[i].simulated = false;
boxCollider2Ds[i].enabled = false;
}
foreach (GameObject obj in visualRooms)
obj.SetActive(true);
}
리지드바디의 기능중에 Sleep함수가 있다. 더이상 작동을 안해도 되는 상황에서 sleep이 true가 되기 때문에 겹침이 사라졌다고 판단할 수 있다.
그 때까지 기다리고 펼침을 위한 리지드바디와 콜라이더는 비활성화 시키고, 실제 오브젝트들을 활성화 시킨다.
방을 만들 때 고려할 사항이 있다.
위와 같은 방법으로 펼쳤다면 콜라이더가 원하는 것과 다르게 딱 달라붙어 있는 경우가 꽤 생긴다.
이를 해결하기 위해서 실제 방보다 크게 만들기 위한 패딩값을 추가한다.
RoomController rc = go.AddComponent<RoomController>();
visualRooms.Add(go);
int xLen = Random.Range(minRoom, maxRoom);
int yLen = Random.Range(minRoom, maxRoom);
BoxCollider2D bc = goo.AddComponent<BoxCollider2D>();
boxCollider2Ds.Add(bc);
bc.offset = Vector3.zero;
bc.size = new Vector2(xLen + roomPadding, yLen + roomPadding);
Rigidbody2D rb = goo.AddComponent<Rigidbody2D>();
rb.gravityScale = 0;
rb.constraints = RigidbodyConstraints2D.FreezeRotation;
rb.bodyType = RigidbodyType2D.Static;
rb.drag = 6;
rigidbody2Ds.Add(rb);
GenerateRoom 함수에서 콜라이더와 리지드 바디를 추가, 설정하는 코드이다.
이 방법으로 하면 자연스레 방끼리 떨어져있게 된다.
다음 글에서는 통로를 어떻게 생성할 것인가를 연구하고 작성해보겠다.
'2d 자동 맵생성' 카테고리의 다른 글
맵 자동 생성(5) (2) | 2025.05.11 |
---|---|
맵 자동 생성(4) (0) | 2025.05.11 |
맵 자동 생성(3) (0) | 2025.05.10 |
맵 자동 생성 (1) (0) | 2025.05.09 |
맵 자동 생성 (0) (0) | 2025.05.09 |