자세히보기

공부 나눔 (Sharing Study)/Unity 와 C#

[Unity/C#] 데이터 저장/불러오기 가장 쉬운 방법 (Json)

윤스톤 2020. 5. 26. 14:53

유니티에서 데이터를 저장하는 방법에 대해 알아보도록 하겠습니다!
이 방법을 통해 게임을 껐다가 켜도 데이터가 유지되도록 할 수 있습니다.
(저는 챕터의 잠금여부를 저장했습니다 : Bool값)

 

1. 데이터 관리 / 저장 할 데이터 스크립트 생성하기

먼저 데이터 저장을 사용할 유니티프로젝트를 열어
Asset 파일 속 원하는 위치에 C#스크립트를 새로 작성해야 합니다.

저는 데이터의 저장과 불러오기를 관리할 스크립트는 DataManager,
저장해야 할 데이터들을 관리할 스크립트는 GameData라는 이름으로 만들었습니다.

 

2. 데이터 관리 스크립트 작성하기

DataController 스크립트를 열어 코드를 적어봅시다.
(pirnt 부분은 선택사항입니다)

using System.IO;
using UnityEngine;

public class DataManager : MonoBehaviour
{
    static GameObject container;

    // ---싱글톤으로 선언--- //
    static DataManager instance;
    public static DataManager Instance
    {
        get
        {
            if (!instance)
            {
                container = new GameObject();
                container.name = "DataManager";
                instance = container.AddComponent(typeof(DataManager)) as DataManager;
                DontDestroyOnLoad(container);
            }
            return instance;
        }
    }

    // --- 게임 데이터 파일이름 설정 ("원하는 이름(영문).json") --- //
    string GameDataFileName = "GameData.json";

    // --- 저장용 클래스 변수 --- //
    public Data data = new Data();


    // 불러오기
    public void LoadGameData()
    {
        string filePath = Application.persistentDataPath + "/" + GameDataFileName;

        // 저장된 게임이 있다면
        if (File.Exists(filePath))
        {
            // 저장된 파일 읽어오고 Json을 클래스 형식으로 전환해서 할당
            string FromJsonData = File.ReadAllText(filePath);
            data = JsonUtility.FromJson<Data>(FromJsonData);
            print("불러오기 완료");
        }
    }


    // 저장하기
    public void SaveGameData()
    {
        // 클래스를 Json 형식으로 전환 (true : 가독성 좋게 작성)
        string ToJsonData = JsonUtility.ToJson(data, true);
        string filePath = Application.persistentDataPath + "/" + GameDataFileName;

        // 이미 저장된 파일이 있다면 덮어쓰고, 없다면 새로 만들어서 저장
        File.WriteAllText(filePath, ToJsonData);

        // 올바르게 저장됐는지 확인 (자유롭게 변형)
        print("저장 완료");
        for (int i = 0; i < data.isUnlock.Length; i++)
        {
            print($"{i}번 챕터 잠금 해제 여부 : " + data.isUnlock[i]);
        }
    }
}

DataManager.cs
0.00MB

(위 코드를 복사하시려면 이 스크립트를 다운받아주세요 - 우클릭 방지)

더보기

[ 코드 설명 💬 ]

유니티에서 지원해주는 System.IO는 폴더 안에 저장 된 게임 파일을 확인하고, 존재유무를 판단하여 불러올 수 있게 해줍니다.

 

데이터 매니저 클래스를 싱글톤으로 관리하기 위해
클래스 안에서 직접 오브젝트 생성, 이름 설정, 클래스 컴포넌트 추가를 한 뒤에
씬이 전환되어도 삭제되지 않도록 DontDestroyOnLoad() 함수를 사용합니다.

 

FileWriteAllText() 매서드는 이미 저장된 파일이 있을 경우 덮어쓰도록 해줍니다.

 

3. 저장 할 데이터 스크립트 작성하기

데이터를 저장하고 불러오기를 해줄 스크립트를 모두 작성했다면
원하는 데이터를 적어둘 스크립트를 작성해야 합니다.

using System;

[Serializable] // 직렬화

public class Data
{
    // 각 챕터의 잠금여부를 저장할 배열
    public bool[] isUnlock = new bool[5];
}

GameData.cs
0.00MB

(위 코드를 복사하시려면 이 스크립트를 다운받아주세요 - 우클릭 방지)


제가 만든 게임은 챕터가 잠겨있고, 이전 챕터를 클리어하면 다음 챕터가 잠금해제 되는 방식의 게임이므로
챕터의 잠금여부를 bool 자료형의 배열로 저장해두었습니다.

더보기

[ 코드 설명 💬 ]

Json으로 전환하여 저장할 수 있도록 [Serializable]public을 통해 직렬화해 줍니다.

(참조 : https://docs.unity3d.com/kr/530/Manual/script-Serialization.html)

 

4. 원하는 부분에서 저장하기 / 불러오기

어떤 스크립트에서든 이 코드만 적어주면 원하는 상황에서 저장할 수 있습니다.

// 원하는 순간에 함수 호출
DataManager.Instance.SaveGameData(); // 저장
DataManager.Instance.LoadGameData(); // 불러오기

예를 들어 세이브 버튼을 누르거나 게임이 종료되는 등 저장이 필요한 상황이나
 게임 시작되는 순간과 같이 불러오기가 필요한 상황에서 호출하시면 됩니다.
데이터 매니저가 싱글톤이기 때문에 언제 어디서든 편하게 접근하여 호출이 가능합니다.

 

5. 다시 실행했을 때 저장되어 있는 데이터 확인하기

데이터를 만들고 저장했다면 제대로 저장되어 있는지 불러오기를 해봐야겠죠?
불러오기 코드는 이미 위에서 작성을 했으니 확인을 해봅시다

샘플용 오브젝트와 스크립트를 만들어두고,
그 안에 위에서 작성한 저장/불러오기 함수를 호출하는 코드를 작성합니다.
DataManager 클래스는 사용될 때 자동으로 오브젝트를 생성하도록 했기 때문에
따로 오브젝트를 만들어서 컴포넌트를 넣어둘 필요가 없습니다.

 

게임을 플레이하면 스타트 함수에 있던 함수 호출에 의해
자동으로 데이터 매니터 오브젝트가 생성되고, 데이터 매니저 스크립트를 컴포넌트로 갖게 됩니다.

 

 

변경사항을 만들어 준 후, 게임을 종료하면 자동으로 저장이 되고,
다시 게임을 시작하면 저장되어있던 값을 불러오는 것을 확인할 수 있습니다.

 

사용한 경로에서 저장된 파일을 열어서 확인할 수도 있습니다.


데이터 저장/불러오기 가장 쉽게 하는 방법이었습니다 :)
끝까지 읽어주셔서 감사합니다! 도움이 되셨다면 댓글+하트 해주세요 🥰

반응형