2d 자동 맵생성

맵 자동 생성(6)

게임만드는학생 2025. 5. 12. 14:08

이전까지 방을 생성해서 다 펼쳐놓고 그 mst를 이용해 방 들을 연결하였다.

그리고 그 간선들을 이용해 문과 벽을 생성하고 통로까지 만들었다. 

 

https://tpree.tistory.com/235

 

맵 자동 생성(5)

이번 글에서는 통로를 완성시켜보겠다. 내가 몇번 살펴본 결과, 통로는 이렇게 2가지이다. ㄷ자, ㄹ자는 등장하지 않는다. 따라서 일자와 위 사진 같은 경로만 만들면 된다.그럼 어떻게할까? 간

tpree.tistory.com

 

이번 글에서는 방 안에 몬스터와 장애물들을 랜덤으로 설치해보려고 한다. 

이것으로 맵 자동 생성은 완성될 듯하다. 

 

우선 몬스터와 장애물 프리팹들은 이미 준비가 되어있다. 아주간단하게 움직이지 않는 오브젝트에 boxCollider만 붙여놓은 것이다. 

 

 

이것들을 방마다 랜덤으로 생성하면 맵 자동완성의 전체적인 틀은 완성하는 것이라고 생각한다. 

 

각 방마다 붙어있는 RoomController.cs 스크립트에 SetCreature라는 함수를 만들어 장애물들과 몬스터를 생성하게 했다. 

이 함수는 RoomGenerator 스크립트에서 호출하게 된다. 

우선 이 함수부터 살펴보겠다. 

public void SetCreature(RoomGenerator rg)
{
    int randMonster = Random.Range(1, 3);
    GameObject[] monsters = rg.CreateMonster(randMonster);

    int randCreature = Random.Range(1, 5);
    GameObject[] objects = rg.CreateRandomCreature(randCreature);

    for(int i=0;i<monsters.Length;i++)
    {
        while (true)
        {
            int randX = Random.Range(2, Width - 3);
            int randY = Random.Range(2, Height - 3);
            Vector2 v = GetCenter();
            if (randX == v.x && randY == v.y) continue;
            if (roomArrayData[randY, randX] == TileType.Floor)
            {
                monsters[i].transform.SetParent(transform);
                monsters[i].transform.localPosition = new Vector2(randX, randY);
                roomArrayData[randY, randX] = TileType.Monster;
                break;
            }
        }
    }
    for(int i=0;i<objects.Length;i++)
    {
        while(true)
        {
            int randX = Random.Range(2, Width - 3);
            int randY = Random.Range(2, Height - 3);
            Vector2 v = GetCenter();
            if (randX == v.x && randY == v.y) continue;
            if (roomArrayData[randY, randX] == TileType.Floor)
            {
                objects[i].transform.SetParent(transform);
                objects[i].transform.localPosition = new Vector2(randX,randY);
                roomArrayData[randY, randX] = TileType.Creature;
                break;
            }
        }
    }
    
}

몬스터와 장애물들을 얼만큼 생성할지 랜덤으로 정한 다음에 RoomGenerator에 있는 함수에게 각각 얼만큼씩 만들어달라고 요청후, GameObject 배열을 리턴받는다. 그것을 이 함수에서 방의 랜덤한 곳에 위치설정만 하는 것이다. 

while문으로 하는 이뉴는 겹치는 것을 방지하기 위해서이다. 

방 데이터를 roomArrayData로 관리하며 각 칸이 어떤 것인지를 체크하는데 Floor에만 생성하도록 지정했다. 

 

이제 RoomGenerator에 있는 함수들을 살펴보겠다. 

public GameObject[] CreateMonster(int num)
{
    GameObject[] go = new GameObject[num];
    for(int i=0;i<num;i++)
    {
        go[i] = Instantiate(prefabMonster, Vector3.zero, Quaternion.identity);
    }
    return go;
}

public GameObject[] CreateRandomCreature(int num)
{
    GameObject[] objects = new GameObject[num];
    for(int i=0;i<num;i++)
    {
        int rand = Random.Range(0, creatures.Length);
        objects[i] = Instantiate(creatures[rand]);
    }
    return objects;
}

public으로 RoomController 에서 호출하도록 했으며 몇개를 생성할지 받은 후, 생성해서 리턴해주는 간단한 기능이다. 

 

CreateRandomCreature 함수는 장애물 자체도 랜덤으로 생성을 하도록 한 것이다. 

 

마지막으로 

void SetRoomCreature()
{
    foreach(RoomController rc in visualRooms)
    {
        rc.SetCreature(this);
    }
}

RoomGenerator 스크립트에 이 함수를 만들어 방의 외형이 다 만들어진 후, 호출하면 방이 완성된다. 

 

 

 

이로써 맵 자동생성은 완성이다. 

엔터 더 건전처럼 맵 자동완성을 구현해보고자 시작했는데 막막했지만 하나씩 하다보니 또 엄청 어렵진 않았다. 

방 안에 어떤 장애물들을 추가하고 이런 것들은 부수적인 것들이라 추가하진 않을 것이다. 

 

다음 글은 번외편으로 몬스터 구현까지 완성해서 프로젝트 플레이 영상을 간단하게 올리고 마무리 지으려고 한다. 

'2d 자동 맵생성' 카테고리의 다른 글

맵 자동 생성(8)  (0) 2025.05.13
맵 자동 생성(7)  (0) 2025.05.13
맵 자동 생성(5)  (2) 2025.05.11
맵 자동 생성(4)  (0) 2025.05.11
맵 자동 생성(3)  (0) 2025.05.10