강의, 책/[Unity] C#과 유니티로 만드는 MMORPG 게임 개발 시리즈

Section 12. Data - Data Manager

hye3193 2024. 2. 4. 11:08

Assets > Resources > Data > StatData.json (유니티 상에서 추가가 안 되니 폴더로 직접 이동하여 만들어준다)

{
    "stats": [
        {
            "level": "1",
            "hp": "100",
            "attack": "10"
        },
        {
            "level": "2",
            "hp": "150",
            "attack": "15"
        },
        {
            "level": "3",
            "hp": "200",
            "attack": "20"
        }
    ]
}

 

Assets > Scripts > Data > Data.Content.cs (클래스명에 .이 들어가서 오류가 뜨지만, 클래스 사용 안 할 거기 때문에 무시)

* data 파일을 어떤 포맷으로 읽어들일 것인가를 나타내기 위한 스크립트 파일

#region Stat

[Serializable]
public class Stat
{
    public int level;
    public int hp;
    public int attack;
}

[Serializable]
public class StatData : ILoader<int, Stat>
{
    public List<Stat> stats = new List<Stat>();
    
    public Dictionary<int, Stat> MakeDict()
    {
        Dictionary<int, Stat> dict = new Dictionary<int, Stat>();
        foreach (Stat stat in stats)
            dict.Add(stat.level, stat);
        return dict;
    }
}

#endregion

* List<T> 형태의 변수명은 반드시 json 파일의 배열명과 일치하여야 한다(본 코드에서는 stats로 일치한다)

 

Assets > Scripts > Managers > DataManager.cs

public interface ILoader<Key, Value>
{
    Dictionary<Key, Value> MakeDict();
}

public class DataManager
{
    // data 추가 시 코드 추가 1
    // 각 요소 별로 고유 값 int를 넣은 딕셔너리 형태로 저장
    // NPC, 몬스터, 퀘스트 등에 고유 id값(int)을 넣어 빠르게 찾아올 수 있다
    public Dictionary<int, Stat> StatDict { get; private set; } = new Dictionary<int, Stat>();
    
    public void Init()
    {
       // data 추가 시 코드 추가 2
        StatDict = LoadJson<StatData, int, Stat>("StatData").MakeDict();
    }
    
    Loader LoadJson<Loader, Key, Value>(string path) where Loader : ILoader<Key, Value>
    {
        TextAsset textAsset = Managers.Resource.Load<TextAsset>($"Data/{path}");
        return JsonUtility.FromJson<Loader>(textAsset.text);
    }
}

 

Managers 스크립트에도 연결해주고 초기화 코드도 넣어준다

DataManager _data = new DataManager();
public static DataManager Data { get { return Istance._data; } }

staic void Init()
{
    if (s_Instance == null)
    {
        s_Instance._data.Init();
    }
}

 

사용 예

Dictionary<int, Stat> dict = Managers.Data.StatDict;