본문 바로가기
ぺ Let's do it ぺ/⒈유니티(Unity3d)

[별아재군/unity3d] 유니티 내장 JsonUtility를 활용한 저장하기, 불러오기 기능 구현하기..

by 망고부인 2021. 9. 4.
728x90

며칠만에 다시 컴퓨터 앞에 앉았다..

그사이에 고라니TV도 좀 다시 보고..

올초에 만들었던 어플도 다시 고민해 보고..

일도 열심히, 다이어트도 열심히...

그러다보니 며칠이 지났네..

어쨌거나.. 다시 시작..

 

오락실 슈팅게임도 아니고..

컴퓨터 게임, 모바일 게임하면서..

동전 넣을때 마다.. 게임 다시 시작할때마다

맨처음부터 다시 게임이 시작된다면..

나는 안한다..

 

그래서 세이브파일에 저장하기,

세이브파일 불러오기가 중요한 것이다..

 

그럼 어떤식으로 로직을, 알고리즘을 구현할 것인지

먼저 고민해 봐야하는데.. 나는 

1. 새게임

2. 불러오기

3. 종료

로 정했다..

 

그렇다면.. 로직의 경우를 생각해 봐야한다.

1. 새게임

   1-1. 세이브파일이 없다면,

         1-1-1 세이브할 데이터를 초기화하고,

         1-1-2 초기화한 데이터로 세이블 파일을 저장

         1-1-3 게임으로 전환 (메뉴씬으로 전환)

   1-2. 세이브파일이 있다면,

         1-2-1 세이브파일이 있는데 정말 초기화 할래? 확인기능 - 향후에 추가

         1-2-2 세이브할 데이터를 초기화하고,

         1-2-2 초기화한 데이터로 세이블 파일을 덮어 저장

         1-2-3 게임으로 전환 (메뉴씬으로 전환)

2. 불러오기

   2-1. 세이브파일이 없다면,

         2-1-1 세이브파일이 없다!! 새게임으로 시작해 - 향후에 추가

   2-2. 세이브파일이 있다면,

         2-2-3 게임으로 전환 (메뉴씬으로 전환)

3. 종료 : 기존처럼 게임 종료

 

이렇게 흐름도를 잡고..

저장 파일을 만들고 불러오기 위해

직렬화를 하고..

유니티에 내장되어 있는 JsonUtility 활용해서..

저장 파일을 만들어 볼 계획이다..

 

먼저 타이틀씬에서 작업을 시작하자..

일단 어떤 내용을 저장할 것인가?

이름, 레벨, 경험치...

먼저 세이브 내용을 묶어넣을 클래스를 만들고..

[System.Serializable] // 직렬화를 위한 선언, 인스펙터 확인, 제이슨 저장 위해서
public class SaveData
{
    // 정상적인 세이브를 위해 숫자도 string형으로 선언
    public string Name, Lvl, Exp;
}

세이브 내용을 저장할 SaveData 클래스형 변수를 선언.

public class TitleDirector : MonoBehaviour
{

    public SaveData MySaveData; // 세이브데이터를 저장할 변수 선언, 인스펙트에 보이게 public으로
    public string filePath; // 세이브파일이 저장될 위치 입력을 위해

}

다음으로 넣어가기 전에 

Start()함수에 저장할 파일의 위치와 파일명을 대입해 놓으면

줄임말? 단축단어? 라고 생각하면 된다.

 

실제로 Debug.Log로 경로를 출력해서..

윈도두 탐색기에 붙여놓기 하고 따라가 봤더니..

이것에 저장이 되더군요..

C:/Users/PC-USER/AppData/LocalLow/DefaultCompany/Adventure2D_Of_3Kingdoms/MySaveData.txt

 

빌드셋팅에서 입력했던 내용으로 폴더가 생성되고

DefaultCompany/Adventure2D_Of_3Kingdoms/

이곳에 MySaveData.txt 파일이 생성됩니다..

 

그전에는 유니티 에디터 에셋 폴더에 생성이 됐거든요.. 

    void Start()
    {

    // 윈도우나 모바일 앱에 게임이 설치된 폴더에 MySaveData.txt 파일 경로

    filePath = Application.persistentDataPath + "/MySaveData.txt";

    }

자~ 그럼 본격적으로.. 스크립트를 통해서..

새게임, 불러오기 버튼에 기능을 구현해 보자

먼저 새게임 버튼을 클릭하면..

OnClickNewGame() 함수 실행..

    public void OnClickNewGame()
    {
        Debug.Log("새게임 - 세이브파일 있니?");

        if (!File.Exists(filePath))     // MySaveDate.txt 세이브파일 존재여부 확인
        {
            Debug.Log("세이브 파일 없다. 새로 시작할자");
            ResetSaveData();    // 세이브 데이터 초기화
            Save();             // 초기화 세이브 데이터를 파일로 저장
            Debug.Log(MySaveData.Name);     // 단계별 확인용 출력
            SceneManager.LoadScene("MenuScene");        // 메뉴씬으로 전환
            return;   // 클래스 종료
        }
        else
        {
            Debug.Log("세이브 파일이 있다. 기존 파일 초기화하고 새로 시작할까?"); // 세이브파일 생성, 레벨 0 초기화
            Debug.Log(filePath);    // 세이브 파일이 저장되는 위치 확인
            ResetSaveData();    // 세이브 데이터 초기화
            Debug.Log(MySaveData.Name);     // 단계별 확인용 출력
            SceneManager.LoadScene("MenuScene");    // 게임씬으로 전환
            return;   // 클래스 종료
        }
    }

다음으로 불러오기..

OnClickLoadGame() 함수 실행

    public void OnClickLoadGame()
    {
        Debug.Log("불러오기 - 세이브파일 있니?");

        if (!File.Exists(filePath))     // MySaveDate.txt 세이브파일 존재여부 확인
        {
            Debug.Log("세이브 파일 없다. 새게임으로 새로 시작해라");
            return;   // 클래스 종료
        }
        else
        {
            Debug.Log("세이브 파일이 있다. 기존 파일로 시작할게");
            Load();     // 기존 세이브 내용 확인하기 위해서 #1-1
            Debug.Log(MySaveData.Name);          // 기존 세이브 내용 확인하기 위해서 #1-2
            SceneManager.LoadScene("MenuScene");
            return;   // 클래스 종료
        }
    }

주석을 달아 놓았기 때문에 크게 어려운 점이 없을 듯함.

 

마지막으로 초기화 하는 함수...

저장.. 불러오기 기능 구현 함수들..

 

먼저, 맨 위에..

using System.IO;    // 파일 입력, 출력을 위해 필요!!

를 입력해야 파일을 저장, 불러오기가 가능하다.. ^^

 

사실 여기가 제일 어려웠다..

파일로 저장하기 위해서는 

저장할 내용들의 직렬화가 필요하고..

그렇게 하기위해

[System.Serializable] // 직렬화 선언을 먼저 해야하고..

Json를 활용해야 하고..

그런데 Json도 몇몇 라이브러리가 있어서..

뭘로 해야하나..

그러다가 유니티 내장 JsonUtility가 있다고 해서..

이걸로 결정은 했는데

어떻게 해야하나.. 등등

다행히 잠자리에 들기전에 오류를 잡을 수 있어서 휴~~

    // 세이브파일 초기화
    public void ResetSaveData()
    {
        Debug.Log("세이브 데이터를 초기화 한다.");
        MySaveData.Name = "New Player";
        MySaveData.Lvl = "0";
        MySaveData.Exp = "0";
    }

    // 세이브 데이터를 세이브 파일로 만들자
    public void Save()
    {
        string jdata = JsonUtility.ToJson(MySaveData);
        File.WriteAllText(filePath, jdata);
    }

    public void Load()
    {
        string jdata = File.ReadAllText(filePath);
        MySaveData = JsonUtility.FromJson<SaveData>(jdata);
    }

여기서는 세이브파일 내에 세이브 내용은 한개만 있어서

그것만 직렬화 하면 됐지만..

만약에 세이브 내용을 1번, 2번 3번 등등

몇가지로 늘린다면..

이것들도 모드 직렬화를 시켜야 하기 때문에

그때는 List라는 기능을 활용해야 하는데..

이것은 내가 소유한 영웅카드 등을 구현할때 정리 할 생각이다..

 

일단.. 타이틀 씬에서는 작업 완료됐고...

다음은 메뉴 씬에서 초기화된 세이브 내용이..

제대로 불러오기가 되는지 구현을 해야 한다..

 

타이클씬에서 처럼.. 다시

SavaData 함수와 [System.Serializable]  직렬화를 다시 선언하지 않아도 된다.

그랬더나 Globalname 어쩐구 오류가 발생했다..

이 원인 찾는데도 한참을 고생했다..

using UnityEngine.SceneManagement; // LoadScene을 사용하기 위해서 필요!! 
using System.IO;    // 파일 입력, 출력을 위해 필요!!

 

public class MenuDirector : MonoBehaviour
{    


    //--------------------------------------------------------------
    public SaveData MySaveData; // 세이브데이터를 저장할 변수 선언, 인스펙트에 보이게 public으로
    public string filePath; // 세이브파일이 저장될 위치 입력을 위해

}

 

메뉴씬에 넘어오면...

이제 정말 저장된 세이브파일을 불러와서

게임을 즐긴다.. (이건 차차 구현)

    // 세이브 데이터를 세이브 파일로 만들자
    public void Load()
    {
        string jdata = File.ReadAllText(filePath);
        MySaveData = JsonUtility.FromJson< SaveData > (jdata);
    }

 

그리고.. 종료하기 전에 누적된 경험치와 레벨을

세이브파일에 저장을 해야하고..

게임을 종료 한다..

 

    // 세이브 데이터를 세이브 파일로 만들자
    public void Save()
    {
        string jdata = JsonUtility.ToJson(MySaveData);
        File.WriteAllText(filePath, jdata);
    }

내가 생각한데로 제대로 진행하는지 확인하기 위해서..

종료를 위해 타이틀씬으로 넘어가기 전에..

세이브 내용 초기화 때 입력된 New Player를

Old Player로 변경을 하고

저장후 타이틀 씬으로 전환하겠다..

이렇게 하면 

새게임을 클릭할때는 New Player 로 출력되는데..

게임진행후 불러오기를 하면 Old Player로 출력되고..

다시 새게임을 클릭하면 다시 New Player 로 출력되는 것을 확인할 수 있다..

아~ 이번 한 주도 보람차다.. ㅋㅋ

 

여기까지.. 진행하는데 도움이 되었던, 응용했던...

유튜브 동영상과.. 블로그는 아래를 참고하시라..


고라니TV - 카트라이더 인벤토리 - 가장 간단한 DB 관리방법
https://youtu.be/GNSD1-y6SeM

 

카트라이더 인벤토리 - 가장 간단한 DB 관리방법

카트라이더 인벤토리를 직접 만들어보면서 아이템과 인벤토리에 관한 아이디어를 얻으세요 엑셀에서 아이템 데이터베이스를 쉽게 메모장으로 연동해 전체 아이템 리스트를 만들고 그 중에서

youtu.be

 

고라니TV - 모바일 JSON 암호화 저장 + 전체 해상도 대응법
https://youtu.be/z-eBBEw8gbw

 

모바일 JSON 암호화 저장 + 전체 해상도 대응법

카트라이더 인벤토리 편과 이어집니다 JSON.Net for Unity 에셋이 에디터에서만 직렬화되는 버그는 프로젝트 세팅 - Other Setting - Api Compatibillity Level을 .Net 4.X 로 바꿔주시면 해결됩니다. 쓰셔도 됩니

youtu.be

 

또노님 - UNITY - JsonUtility 를 이용한 JSON 파일 저장 및 불러오기
https://blog.naver.com/sleepygloa/222480192439

[출처] UNITY - JsonUtility 를 이용한 JSON 파일 저장 및 불러오기|작성자 또노

 

UNITY - JsonUtility 를 이용한 JSON 파일 저장 및 불러오기

유니티를 하면서 데이터 저장 하는 방법이 필요해 JSON 형태로 저장하는 방법을 알아 보았습니다. 1. ...

blog.naver.com

오늘은 여기까지 정리할게요..

 

다음에는 메뉴씬에서 왼쪽 상단에..

내 세이브파일 저장내용..

게이머 이름, 레벨, 경험치 게이지 등을 구현해 보려고 합니다..

 

728x90

댓글