Unity_개발일지_42

홍신영·2024년 12월 18일
0

Unity

목록 보기
44/61

오늘도,, 던전 데이터 작업을 진행하였다.

먼저 기존에 사용하던 데이터이다.

StageId로 딕셔너리의 키값을 받아 objectname에 스테이지 이름을, SpawnMonster를 통해 소환할 몬스터의 이름 그리고 생성할 갯수를 종류별로 1,2,3로 받는 식으로 진행되었다.
물론 4,5,6 이렇게 더 한 스테이지에 더 많은 종류의 몬스터를 생성할 수도 있지만, 보는 것도 많아지면 불편할 것이고, json에서 클래스로 바꾸어줄때에도 많은 줄을 차지 하게 되는 문제가 있었다.

그래서 바꾼 방식을 소개한다.

다음과 같이 StageId와 스테이지명이 될 ObjectName은 그대로 가고, 아까와는 다르게 종류, 갯수만 만들어 이들의 자료형을 string으로 주었다.

이걸 어떻게 할지 벌써 감이 올 것이다.
'/'를 split해주어 string[]로 사용을 하면 기존과 같은 결과를 가질 수 있는 것.

이제 본격적으로 json에서 클래스로 만들어주자.

[System.Serializable]
public class MonsterSpawnData
{
    public string SpawnMonster;
    public string MonsterCount;

    public MonsterSpawnData(string spawnMonster, string monsterCount)
    {
        SpawnMonster = spawnMonster;
        MonsterCount = monsterCount;
    }
}

[System.Serializable]
public class MetaDungeonData : DataBase<MetaDungeonData>
{
    public string StageId;
    public string ObjectName;
    [SerializeField] private string SpawnMonster;
    [SerializeField] private string MonsterCount;
    public List<MonsterSpawnData> MonsterSpawnList = new List<MonsterSpawnData>();

    public override void SetData(MetaDungeonData metaData)
    {
        this.StageId = metaData.StageId;
        this.ObjectName = metaData.ObjectName;
        AddMonsterSpawnData(metaData.SpawnMonster, metaData.MonsterCount);
    }

    private void AddMonsterSpawnData(string spawnMonster, string monsterCount)
    {
        if (string.IsNullOrEmpty(spawnMonster) == false)
        {
            MonsterSpawnData monsterSpawnData = new MonsterSpawnData(spawnMonster, monsterCount);
            MonsterSpawnList.Add(monsterSpawnData);
        }
    }
}

여기서 먼저 한 것은 어제의 연결부분에서 불편함을 주었던, 스테이지와 몬스터를 분리하는 작업이였다.
MetaDungeonData에 시트에서 만든 변수를 정의하고, 몬스터 스폰에 관련한 부분은 따로 클래스에 입력해주고 이를 리스트로 받아줄 것이다.
생성자를 통해 리스트에 전달해주고 리스트에 가져온 두 스폰정보를 추가해주면 된다.

다음으로 딕셔너리로 만들어주고 키 값으로 편하게 불러오자.

[System.Serializable]
public class DungeonDataList : DataBaseList<string, MetaDungeonData, MetaDungeonData>
{
    public List<MetaDungeonData> Dungeon;
    public override void SetData(List<MetaDungeonData> metaDataList)
    {
        datas = new Dictionary<string, MetaDungeonData>(metaDataList.Count); //딕셔너리 초기용량 지정
        metaDataList.ForEach(obj =>
        {
            MetaDungeonData dungeon = new MetaDungeonData();
            dungeon.SetData(obj);
            datas.Add(dungeon.StageId, dungeon);
        });
    }
}

이렇게 딕셔너리로 바꾸는 작업을 해주고, 데이터 매니저에서

    private DungeonDataList dungeonDataList;
    public DungeonDataList DungeonDB => dungeonDataList ??= LoadData<DungeonDataList, DungeonDataList>("Dungeon", data =>
    {
        dungeonDataList = new DungeonDataList();
        dungeonDataList.SetData(data.Dungeon);
        return dungeonDataList;
    });
    
    //로드
        private T LoadData<T, M>(string resourceKey, System.Func<M, T> customAction = null) where T : new()
    {
        TextAsset data = ResourceManager.Instance.LoadAsset<TextAsset>(resourceKey, eAssetType.JsonData);
        if (data != null)
        {
            Debug.Log($"JSON 파일 로드 성공: {resourceKey}");
            M MetaDataList = JsonUtility.FromJson<M>(data.text);
            var loadData = customAction.Invoke(MetaDataList);
            return loadData;
        }
        else
        {
            Debug.LogError($"{resourceKey} 데이터 불러오기 실패");
            return default;
        }
    }

데이터 파트에서 잘 연결해주셨다..
어쨋든 가져온 데이터를 활용해보자.

초기화 부분에

    public void InitializeDungeon(string stageId)
    {
        PuzzleManager = new GameObject("PuzzleManager").AddComponent<PuzzleManager>();
        curStageId = stageId;
        MetaDungeonData stageData = DataManager.Instance.DungeonDB.LoadData(stageId);
        SpawnStageObjects(curStageId, stageData);
        Debug.Log("현재 스테이지: " + curStageId);
    }

데이터매니저에서 아까만든 딕셔너리의 키 값으로 데이터를 로드해주고,
맵은 넘어가겠다. 바로 몬스터로 보면 여전히 string으로 /가 붙어있는 상태이기에 이를 바꿔주는 작업을 해준다.

string[] spawnMonsterArray = SpawnMonster.Split('/');
string[] monsterCountArray = MonsterCount.Split('/');

이렇게 문자열 배열에 split을 통해 하나씩 넣어준다.
그리고 몬스터 종류는 문자열로 사용할테니 놔두고, 스폰할 count는

if (int.TryParse(monsterCountArray[i], out int count))

TryParse를 이용하여 예외처리겸 int로 바꾸어주는 작업을 해주면 된다.

그 다음으로는 어제와 동일하다. 생성해주기전에 mapdata컴포넌트 불러와서 거기에서 지정한 spawnpoint의 Transform을 반환받아 그 위치에 생성해주면 끝이다.

이제 진짜 데이터 구조는 안바뀌지 않을까 싶다.
사실 작성하지는 않았지만 이전에는 1스테이지 아이디가 여러개로 그에 맞는 몬스터 맵을 불러오는 방식을 사용하기도 했고, 그러니 중복 스테이지가 되어 확인이 어렵고, 등,,많은 데이터 구조의 변화가 있었던 것 같다.
초반에 설계를 잘하자..화긴

profile
게임 클라이언트 개발자

0개의 댓글