내일배움캠프/프로젝트

팀 프로젝트 - 아이템 무작위 배치

서보훈 2025. 1. 8. 20:22

맵을 구성함과 동시에, 아이템을 무작위로 배치하는 기능을 만들어주었습니다.

노란색 아이콘이 아이템이 배치될 위치를 지정해둔 오브젝트들 입니다.

 

맵 데이터에 아이템이 생성될 위치를 가진 부모 오브젝트를 등록시켜둔 상태이며, 각 건물 프리팹 내에 아이템이 스폰될 수 있는 위치를 지정하는 빈 오브젝트를 만들어둔 상태입니다.

 

맵 프리팹은 생성되면서 부모 오브젝트의 자식 오브젝트들을 전부 가져온 뒤, 리스트에 Transform 을 저장하도록 만들어주었습니다.

public class MapData : MonoBehaviour
{
    //...생략

    private void Awake()
    {
        foreach (Transform t in studentItemSpawnPosParents)
        {
            Transform[] eachPositions = t.GetComponentsInChildren<Transform>();
            foreach(Transform positions in eachPositions)
            {
                if(positions == t) continue;
                studentItemSpawnPos.Add(positions);
            }
        }

        itemSpawnPositionCount = studentItemSpawnPos.Count;

        GameManager.Instance.mapData = this;
    }
}

 

아이템을 무작위로 스폰하는 메서드 입니다.

유령 프리팹이 생성된 직후에 이 메서드를 호출하도록 하였습니다.

//무작위 아이템 스폰
private void SpawnItems()
{
    List<int> spawnIndex = new List<int>(50);
    for(int i = 0; i < GameManager.Instance.mapData.itemSpawnPositionCount; i++)
    {
        int index = Random.Range(0, i + 1);
        spawnIndex.Insert(index, i);
    }

    int maxIndex = DataManager.Instance.GetKeyCount(EDataType.ItemData);

    for (int i = 0; i < GameManager.Instance.mapData.itemSpawnCount; i++)
    {
        int randomIndex = Random.Range(0, maxIndex);
        Transform target = GameManager.Instance.mapData.studentItemSpawnPos[spawnIndex[i]];
        Instantiate(DataManager.Instance.GetDataByInt<ItemData>(randomIndex).ItemPrefab, target.position, Quaternion.identity);
    }
}

아이템 생성 위치의 길이만큼 int 를 저장하는 List 를 만들면서, 각 인덱스에 0 부터 생성 위치 - 1 까지 값이 무작위로 배치되도록 만들어주었습니다.

 

이후, Random 클래스를 통해 무작의 정수값을 얻은 뒤, 데이터 매니저에서 무작위 정수값에 해당되는 인덱스의 아이템을 맵 데이터에 저장된 아이템 생성 갯수만큼 반복하여 무작위로 생성하도록 하였습니다.

 

이 외에도 빛을 조절하여 분의기를 만들거나, 1 ~ 3분 간격으로 무작위 효과음을 재생하는 기능을 추가하였습니다.

 


트러블슈팅

  • 아이템 생성 위치 리스트의 Count가 0으로 나오는 현상

아이템을 배치할 때, 위치 리스트를 받아올때 0으로 받아오면서 Out of Range 오류가 발생하는 문제가 있었습니다.

 

해당 문제의 경우, 맵을 생성하면서 GameManager에 맵 리스트의 프리팹 정보를 저장한 뒤, 저장된 MapData 객체 정보를 기반으로 아이템을 생성하면서 발생한 문제였습니다.

 

위에서 보신것과 마찬가지로 아이템 생성 위치를 Awake 문에서 추가하는 방식을 사용해주었습니다.

현재 01번 맵 구성이 아이템 생성 위치 오브젝트가 40개가 넘어가기때문에 해당 방식을 사용하였습니다.

 

그 결과, Awake문이 작동하지 않은 MapData를 사용하여 아이템 생성 시도시, 아이템 생성 위치 리스트는 0 인 상태로 생성을 시도하게 되어 문제가 발생하였습니다.

 

이후 MapData의 Awake 문의 마지막에 GameManager 에 저장된 MapData 를 자신으로 변경하도록 만들어서 해당 문제를 해결하였습니다.