게임 내에 존재하는 미션 목록을 가져와 노출하고, 미션 클리어 여부를 저장하여 관리하기 위해 json을 사용하게 되었다.
UnityEngine의 Inspector 부분에서 미션의 내용을 관리하는게 아닌 Json
에 담아주고 Json
파일을 읽어오는 방안을 사용하고자 하였다.
Parsing이란?
JSON, XML 등으로 구성된 데이터를 내가 원하는 부분만 추출하는 것을 의미합니다.
내가 만들고자 하는 게임에서는 Stage가 존재하며 그 Stage에 따라 미션이 다르기에 Json에서 아래와 같이 구분을 해주었다.
다만 이렇게 계층과 구분을 두어 여러 데이터를 받아보기 위해서는 조금 귀찮은 작업이 필요하다.
Json
을 보면 stage1 - {stageNum, ...}과 같은 계층을 나눠져있길래 이와 같은 구조로 묶어주어야한다. class로 묶어도 되지만 힙에 할당되는 것이 싫어서 struct를 사용하여 Json
에서 받아올 데이터의 타입들과 동일하게 선언해주고
변수들이 담긴 struct(MissionInformation)
를 가진 struct(MissionInfor)
를 선언하여 받아올 것이다.
이때
MissionInfor
struct에 선언한MissionInformation
의 변수명은 Json에서 사용한 구분 명과 동일해야한다.
FileStream
Class를 사용하여 저장해둔 파일을 불러오는 방식을 사용할 것이다. 불러오는 경로는 Application.persistentDataPath
를 사용하는데 여기는
C:\Users\사용자명\AppData\LocalLow\회사명\프로젝트명
이 경로이다. 위에서 만들어둔 Json파일을 해당 경로에 저장 해주자.
using System.IO;
MissionInfor missionData;
void Awake() // Stage 변경 시에 해당 정보 받아오기
{
FileStream fs = new FileStream(path, FileMode.Open); // 경로에 있는 파일을 열어주고,
StreamReader stream = new StreamReader(fs);
string data = stream.ReadToEnd();
missionData = JsonUtility.FromJson<MissionInfor>(data); //Json data를 MissionInfor 타입으로 변환해준다.
stream.Close(); // 사용 후에는 꼭 닫아준다.
}
string path { get => Application.persistentDataPath + "/MissionInformation.json"; }
기존에는 불러올 때는 간편한 Resources.Load()
를 사용했으나 성능 이슈가 있다고 하여 더 자세한 공부를 하기전에는 FileStream
방식으로 대체하여 사용하고자한다.
이렇게 Json으로 저장된 파일을 파싱해오면 missionData
라는 곳에 원하는 데이터가 담겼고, 이를 사용해주면 된다.
저장은 비교적 더 간단하다. File의 WriteAllText를 통해 저장하면서 JsonUntility를 통해 타입 변경만 해주면 생각하던 대로 저장되고 불러올때 저장된 데이터로 불러와진다.
File.WriteAllText(path, JsonUtility.ToJson(MissionInfor));
string path { get => Application.persistentDataPath + "/MissionInformation.json"; }
이렇게 저장해둔 데이터를 통해 받아온 string 값을 textmeshpro와 연결하여 내용을 입력해주었고, bool 값 체크로 이미 클리어가 되어있으면 클리어된 상태로 불러와지게 변경해주는 방식으로 활용하였다.
혹시 간편한 방법을 원할 수 있어 간단하게 정보를 남긴다. Resources.Load()
는 유니티에서 지원하는 파일 입력 기능이다. 정말 간단하게 파일을 불러와서 사용할 수 있다.
TextAsset textAsset = Resources.Load<TextAsset>("MissionInformation");
missionData = JsonUtility.FromJson<MissionInfor>(textAsset.text);