JSON(JavaScript Object Notation)은 속성-값 쌍 및 배열(또는 기타 직렬화 가능)로 구성된 데이터 개체를 저장 및 전송하기 위해 사람이 읽을 수 있는 텍스트를 사용하는 개방형 표준 파일 형식 및 데이터 교환 형식입니다.
필자는 게임 내 대사와 같은 텍스트 데이터들을 QuotesManager.cs에서 보여진 것 처럼 JSON 파일 포맷을 이용해 게임 내 대사나 다른곳에 사용되는 텍스트들을 관리하고 다국어 지원을 쉽게 하도록 구현하였다.
//QuotesManager.cs
...
//JSON 파일 포맷을 읽고 역 직렬화 하기 위한 기능을 사용하기위해 포함시킨다.
using Newtonsoft.Json;
...
//JSON 파일포맷의 데이터 형식이 대사id와 대사text로 되어있어 이를 직관적으로 전달하기위해 만든 구조체이다.
public struct QuoteData
{
public int id;
public string text;
public QuoteData(int id, string text)
{
this.id = id;
this.text = text;
}
}
public class QuotesManager : MonoBehaviour
{
...
private Dictionary<int, string> mQuotesDictionary;
...
private void Start()
{
...
//Json으로부터 데이터를 추출하는 작업을 거친다.
mQuotesDictionary = new Dictionary<int, string>();
//옵션 데이터 중 언어에 띠라 읽는 파일이 다르다.
//필자가 작성한 스크립트에서 0은 한국어로 설정하였다.
if (mOptionDataManager._OptionData.languageID == 0)
{
//유니티의 Resources.Load 함수를 이용해 quotes 파일을 읽는다. 실제 파일명은 quotes.json이지만 'json'은 명시하지 않아야 읽을 수 있다.
var jsonData = Resources.Load("Data/quotes") as TextAsset;
//TextAsset 데이터를 Newtonsoft.Json의 기능인 JsonConvert.DeserializeObject로 역 직렬화를 수행한다.
var jList = JsonConvert.DeserializeObject<List<QuoteData>>(jsonData.text);
//jList의 length만큼 foreach loop 하여 멤버변수인 mQuotesDictionary에 순차적으로 삽입한다.
foreach (var data in jList)
{
this.mQuotesDictionary.Add(data.id, data.text);
}
}
//한국어가 아닌경우는 영어 파일을 읽도록 하였다.
else
{
var jsonData = Resources.Load("Data/quotes_ENG") as TextAsset;
var jList = JsonConvert.DeserializeObject<List<QuoteData>>(jsonData.text);
foreach (var data in jList)
{
this.mQuotesDictionary.Add(data.id, data.text);
}
}
...
}
//딕셔너리로부터 데이터를 받아온다.
private string GetQuote(int quoteID)
{
if (mQuotesDictionary.TryGetValue(quoteID, out string quote))
{
return quote;
}
Debug.LogError("No Quote Data. from id: " + quoteID);
return null;
}
...
//기본이 되는 함수. 지정한 말풍선 ID에 대사를 출력하도록 한다. 리턴은 텍스트가 끝나는 시간을 나타낸다.
public float DisplayQuote(int targetTextID, int quoteID, float duration = mcDefaultDuration, float textCharDelay = mcTextCharDelay, float fadeSpeedMultiply = mcFadeSpeedMultiply, string text = "", QuoteDirection direction = QuoteDirection.NO_CHANGE)
{
...
if (text == "")
{
tempString = GetQuote(quoteID);
}
...
}
}
|
cs |
이전 게시글에서 다룬 QuotesManager.cs(대사 매니저)에서 JSON을 추출하여 데이터셋으로 관리하는 방법을 핵심으로 다룬다.
using Newtonsoft.Json;
- JSON파일 형식으로 이루어진 TextAsset을 역직렬화(Deserialize)하기위한 기능을 추가하기 위해 포함시킨다.
- 이전에는 (Unity 2018, 2021버전) 별도로 다운받아 패키지에 포함시켜야 했지만 Unity2022 버전에서는 패키지에 기본으로 포함되어있는것을 확인하였다. (Unity 2022.1.8f1 버전, 2022/07/18 기준)
public struct QuoteData { }
- JSON파일 포맷의 데이터를 직관적으로 전달하기위해 만든 구조체이다.
private Dictionary<int, string> mQuotesDictionary;
- 수 많은 데이터셋을 효과적으로 꺼내 사용하기위해 딕셔너리 구조를 사용하였다.
- 딕셔너리는 해시를 사용하여 주소를 통해 직접 대상을 탐색하기에 데이터를 수정하지 않고 이미 준비된 데이터들을 탐색하는 용도로 사용하기 적합하다.
- 대사 텍스트라는 것 자체가 이미 준비되어있는 텍스트들의 집합이고, 게임 내에서는 이 대사 데이터들이 수정되지 않기에 사용하기 적합하다고 판단하였다.
- Dictionary 구조체는 해시를 사용하기에 아래 그림처럼 Specific Element를 탐색하는데 소요되는 시간복잡도는 O(1), 상수시간이다. 반면에 List나 LinkedList는 해당 위치를 순환하며 찾아야하기에 O(n)의 복잡도를 지닌다.
private void Start()
- 씬이 로드되면 JSON파일을 읽고, 언어설정을 확인 후 적합한 파일을 읽고 역직렬화를 통해 텍스트 데이터를 준비한다.
- if (mOptionDataManager._OptionData.languageID == 0) 옵션 데이터 매니저에 languageID를 참조하여 어떠한 파일을 읽을지 결정한다. 필자의 스크립트에서는 0은 한국어, 그 외는 영어 텍스트로 지원하기로 하였다.
- var jsonData = Resources.Load("Data/quotes") as TextAsset; 유니티 에셋의 /Assets/Resources에서 ./Data/quotes를 읽어 파일 안의 전체 문자열을 TextAsset으로 가져온다.
- var jList = JsonConvert.DeserializeObject<List<QuoteData>>(jsonData.text); 스크립트에 포함시킨 Newtonsoft의 기능으로 역직렬화를 한다. JSON파일 내부는 int형과 string형으로 되어있어 QuoteData타입의 List로 저장하도록 한다.
- this.mQuotesDictionary.Add(data.id, data.text); 효율적인 탐색을 위해 List를 Dictionary로 만들어 저장해준다.
private string GetQuote(int quoteID)
- 딕셔너리의 사용 방법인 TryGetValue()함수를 이용하여 quoteID를 통해 quote 텍스트 데이터를 받아오도록 한다. 게임 내에서 존재하지 않은 텍스트ID를 가져오라고 요청한경우, 이것은 버그이기에 LogError로 찾아낼 수 있도록 한다.
public float DisplayQuote(...)
- 대사를 출력하기 위한 DisplayQuote함수에서 대사를 가져올 때 위에서 다룬 함수인 GetQuote()함수를 호출하여 대사 텍스트를 가져오도록 한다.
'unity game modules' 카테고리의 다른 글
[유니티] 카메라 벽 통과 방지(카메라암) (0) | 2022.07.19 |
---|---|
[유니티] 사운드를 편하게 관리하는 사운드매니저 (0) | 2022.07.19 |
[유니티] 대사 말풍선 기능 (0) | 2022.07.17 |
[유니티] 오브젝트와 UI에 gif 이미지 출력 (0) | 2022.07.17 |
[유니티] 번개 효과 (0) | 2022.07.17 |