[Unity] Data

이정석·2023년 7월 4일
0

Unity

목록 보기
13/22

Data

게임에서 hp나 패턴과 같은 게임에 대한 정보를 데이터로 관리하게 되는데 이를 다루기 위한 방법이 필요하다.

코드에 직접 작성하는 하드코딩방법은 이후에 재배포나 수정할 때 전체코드를 컴파일해야 할 수도 있다.

온라인 게임의 경우 클라이언트가 다루는 Data format과 서버가 다루는 Data format을 통일해야한다. 보통 json이나 xml을 많이 사용한다.

1. json load

txt파일이나 xml, json파일을 다룰 때 TextAsset이라는 객체를 사용한다. TextAsset에는 text, bytes, name, hashCode등 많은 변수와 함수를 가지고 있다. 특정경로에 있는 json파일을 Load하는 코드는 아래와 같다.

	TextAsset textAsset = Resources.Load<TextAsset>(path);

2. json parsing

textAsset.text에는 불러온 json의 내용이 문자열 형식으로 저장되어 있는데 Unity는 JsonUtility라는 Json 관련 유틸리티를 제공해준다.

1. 불러오기 위한 json 구조 클래스 정의

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

[Serializable]
public class StatData
{
    public List<Stat> stats = new List<Stat>();
}

각 클래스 위에 [Serializable]을 붙여준다.

2. JsonUtility 사용

 StatData data = JsonUtility.FromJson<StatData>(textAsset.text);

data의 List에 json에 작성되어 있는 값들이 자동으로 할당된다. 구조에 key값과 class의 변수명을 통일해야 FronJson에서 불러와진다.

ToJson은 반대로 Data -> Json을 지원한다.


일반화

위 코드에서는 Stat이라는 Data를 불러오는 것을 구현했는데 이후에 Stat외 다른 Json파일을 불러오기 위한 구조를 만들어야할 필요가 있다. Load구조를 일반화 하기 위해 다음과 같은 점을 고려할 수 있다.

  • 한 Element를 나타내는 Class와 List를 나타내는 ListClass가 존재한다.
[Serializable]
public class Stat
{
    public int level;
    public int hp;
    public int attack;
}

[Serializable]
public class StatData
{
    public List<Stat> stats = new List<Stat>();
}
  • 최종결과는 <key, value>형식의 Dictonary이다.

ListClass에서 Dictonary를 반환할 것을 나타내는 Interface를 정의한다.

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

[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;
    }
}
  • Key, Value, ListClass를 Generic으로 둔다.

Return type, Key, Value를 Generic으로해 이후에 추가될 Json에 대한 Data를 가져올 때, 밑의 LoadJson을 사용하면 된다.

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);
}
profile
게임 개발자가 되고 싶은 한 소?년

0개의 댓글