본문 바로가기

유니티

[Unity] 유니티의 데이터 저장 방법들과 그 경로

유니티의 데이터 저장

유니티로 게임을 만들다 보면 유저의 데이터를 저장해야 하는 일이 생긴다. 닉네임이라던지, 레벨이라던지..

 

이런 데이터를 저장하는 기초적인 방법은 다음과 같다.

 

  1. 데이터베이스에 연결해 저장
  2. 유니티에서 제공하는 PlayerPrefs 이용
  3. Json, Xml과 같은 파일에 저장

(물론 이 외에도 여러 가지 방법들이 존재한다)

 

1번 방법은 별도로 필요한 게 많고 복잡하지만 유저가 데이터를 조작하는 걸 막을 수 있다.

 

2, 3번 방법은 간단하지만, 컴퓨터에 파일로 데이터를 저장하므로 유저가 데이터를 조작할 수 있다.

 

이번 강좌에서는 2, 3번 방법을 설명할 예정이다. 1번 방법은 https://yourpresence.tistory.com/87 이 글에 자세히 나와있다.

 

PlayerPrefs를 이용한 데이터 저장

유니티에서 자체적으로 제공하는 기능인 PlayerPrefs를 이용해 데이터를 간단히 저장하고 불러올 수 있다.

 

PlayerPrefs에는 다음과 같은 메서드들이 존재한다.

 

  • void DeleteAll()
  • void DeleteKey(string name)
  • bool HasKey(string name)
  • float GetFloat(string name)
  • int GetInt(string name)
  • string GetString(string name)
  • void SetFloat(string name, float value)
  • void SetInt(string name, int value)
  • void SetString(string name)

DeleteAll은 이름대로 모든 키를 지우고, DeleteKey 함수는 인자로 넘겨준 키 값의 데이터를 삭제한다.

 

HasKey는 해당 이름으로 저장된 키가 있는지 확인하고, 그 결과를 bool값으로 넘겨준다.

 

여기서 핵심은 Set~과 Get~ 함수다.

 

SetFloat는 Float형 자료형의 데이터를 저장하고, SetInt는 Int형, SetString은 String형의 데이터를 저장한다.

 

GetFloat는 Float형 자료형의 데이터를 불러오고, GetInt는 Int, GetString은 String형의 데이터를 불러온다.

 

 

간단한 예제를 살펴보자.

 

public class Example : MonoBehaviour{
    void Start() {
    	if(!PlayerPrefs.HasKey("level"))
    	    PlayerPrefs.SetInt("level", 0)
        Debug.Log(String.Format("Level : {0}", PlayerPrefs.GetInt("level")));
    }
}

다음 코드는 HasKey 메서드로 level이라는 키값이 있는지 확인하고, 없다면 값을 0으로 해 새로 생성한다.

 

그리고, GetInt 메서드로 level값을 가져와 콘솔에 출력한다.

 

Int, String, Float 모두 비슷한 방법으로 처리하면 된다.

 

Get~ 메서드로 값을 가져올 때, 해당되는 키가 없다면 에러가 날 수 있으므로 항상 HasKey 메서드를 이용해 먼저 체크하는 것이 좋다.

 

PlayerPrefs의 저장 경로

PlayerPrefs의 데이터는 다음 경로에 저장된다. http://ancardwineugene.blogspot.com/2015/07/unity3d-playerprefs.html 글을 참고하였다.

 

 

Windows OS

 애플리케이션 - (레지스트리) 레지스트리 HKCU/Software/[company name]/[product name]

 웹플레이어 - %APPDATA%/Unity/WebPlayerPrefs/[company name]/[product name]/

 

Mac OS

 어플리케이션 - ./Library/Preferences/

 웹 플레이어 - ./Library/Preferences/Unity/WebPlayerPrefs/

 

[company name]과 [product name]은 유니티 에디터의 Player Setting에서 설정 가능한 값들이다.

 

 

Json을 이용한 데이터 저장

Json 말고도 Xml, Yaml 등등 많은 데이터 직렬화 양식이 있지만, Json은 여러 모듈도 있고, 더 간단하다.

 

Unity에서 자체 제공하는 JsonUtility가 있긴 하지만, 필자는 LitJson 모듈이 더 익숙하고, 편하다고 생각해 이 강좌에서는 LitJson 모듈을 활용한 데이터 저장을 살펴보겠다.

 

litjson.net 에서 다운로드할 수 있다. / 0.9 버전 다운로드 링크 - github.com/LitJSON/litjson/releases/download/v0.9.0/LitJson.dll

 

*모든 코드는

using LitJson;

을 붙여야 작동한다.

 

경로

유니티에서 파일을 저장할 때는, PlayerPrefs와 다르게 직접 그 경로를 설정해주어야 한다.

 

chameleonstudio.tistory.com/62 글을 참고했다.

 

 

Windows OS

 Application.dataPath - 프로젝트 폴더 내부

 Application.streamingAssetsPath 프로젝트 폴더 -> 에셋 폴더

 Application.persistentDataPath - C:\Users\[user name]\AppData\LocalLow\[company name]

 

Mac OS

 Application.dataPath - 프로젝트 폴더 -> 에셋 폴더

 Application.streamingAssetsPath - 프로젝트 폴더 -> 에셋 폴더 -> StreamingAssets 폴더

 Application.persistentDataPath - 라이브러리 > Application Support > [company name] > [product name]

 

저장 기능

LitJson 모듈은 JsonMapper.ToJson 메서드로 Object를 Json 데이터로 변환할 수 있다.

 

다음 예제 코드를 봐보자.

public class Data {
    public int level;
    public string name;
    public Data(int level, string name){
    	this.level = level;
        this.name = name;
    }
}

public class Example : MonoBehaviour {
    void Start() {
        Data data = new Data(10, "DevRuby");
        save(data);
    }
    void Save(Data data) {
    	JsonData jsondata = JsonMapper.ToJson(data);
        System.IO.File.WriteAllText(Application.persistentDataPath + @"\data.json", jsondata.ToString());
    }
}

데이터 클래스를 새로 생성하고, ToJson 메서드를 이용해 JsonData 타입의 jsondata를 생성하고,

 

Application.persistentDataPath\data.json 경로에 jsondata를 저장한다.

 

data.json의 내용은 다음과 같을 것이다.

 

{
    "level" : 10,
    "name" : "DevRuby"
}

 

불러오기 기능

저장 기능의 구현을 끝냈으니, 이제 저장한 Json 파일을 불러오는 기능을 구현해보자.

 

JsonMapper.ToObject 메서드로 Json(string)을 Object로 변환할 수 있다.

 

저장 기능의 코드에 맞춰 코드를 짜 보겠다.

 

public class Data {
    //생략
}
public class Example : MonoBehaviour {
    void Start() {
        Data data = new Data(10, "DevRuby");
        save(data);
        JsonData json = Load();
        
        Debug.Log(json["level"].ToString());
        Debug.Log(json["name"].ToString());
    }
    void Save(Data data) {
    	//생략
    }
    JsonData Load() {
        string jsonString = System.IO.File.ReadAllText(Application.persistentDataPath + @"\data.json");
    	JsonData jsondata = JsonMapper.ToObject(jsonstring);
        return jsondata;
    }
}

json 파일의 텍스트를 읽어오고, 텍스트를 JsonData 타입으로 변환한다.

 

JsonData는 딕셔너리처럼 키값을 넣어 사용이 가능하다.

 

또한, JsonData[key] 로 불러온 값은 여전히 JsonData 형식이기 때문에, ToString 함수를 이용해 문자열로 만들어줘야 한다.

 

ex) data["money"] / json["data1"]["data2"]

 

 

마무리

지금 살펴본 것들 외에도 수많은 저장 방법이 있다. 오늘은 그중 딱 2가지의 방법만 알아보았다.

각각의 저장방법들은 개성이 뚜렷하고, 장/단점들이 있다. 따라서 어떤 한 가지의 방법이 좋은 게 아니고 경우에 따라 다양하게 사용하면 된다.