2d 자동 맵생성

맵 자동 생성(2)

게임만드는학생 2025. 5. 9. 15:25

이 글에서는 이전 글에서 만든 방을 여러개 만들어서 어떻게 펼칠 것인가를 알아보겠다.

 

https://tpree.tistory.com/231

 

맵 자동 생성 (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