2 분 소요

Intro

이번 포스팅에서는 각종 데이터들을 관리하는 데이터매니저(DataManager) 클래스를 작성해보았습니다.

DataManager는 PlayerData, SkillData, WeaponData 등의 여러 데이터들을 저장 및 로드하는 기능을 합니다.

또한 싱글톤으로 작성하여 어떤 스크립트에서 데이터값에 접근할 수 있도록하는 접근자 메서드를 제공합니다.

 

DataManager의 Save & Load 기능은 제네릭타입으로 선언하여 어떤 데이터타입이 들어와도 처리가능하도록 했습니다.

그리고 데이터타입에 맞는 파일명의 json 파일로 Save & Load 하도록 했습니다.

DataManager 클래스

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

/// <summary>
///                             DataManager 
///                     1. 각 데이터 로드 및 세이브
///                     2. 각 데이터에 대한 접근자 메서드 제공 
///                     3. 임시 데이터 생성
/// </summary>
public class DataManager : MonoBehaviour
{
    // 싱글톤
    private static DataManager instance;

    // 데이터 경로
    private string dataPath;

    private PlayerData playerData;

    public static DataManager Instance
    {
        get
        {
            if (instance == null)
            {
                // 인스턴스가 존재하는지 한번 더 체크
                instance = FindObjectOfType<DataManager>();

                // 없다면
                if (instance == null)
                {
                    GameObject obj = new GameObject("DataManager");
                    instance = obj.AddComponent<DataManager>();
                }
            }
            return instance;
        }
    }


    private void Awake()
    {
        if(instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }

        dataPath = Path.Combine(Application.persistentDataPath + "/Data", "/data.json");

        // 임시
        if(!File.Exists(dataPath))
        {
            InitData();
        }
        else
        {
            LoadCachedData();
        }
    }

    private void InitData()
    {
        // 임의 플레이어 데이터생성
        playerData = new PlayerData(1000f, 1000f, 1000f, 1000f, 3f, 10f);
    }

    private void LoadCachedData()
    {
        playerData = LoadData<PlayerData>("PlayerData");
    }

    //  데이터 저장
    public void SaveData<T>(T data, string fileName = "")
    {
        string jsonData = JsonUtility.ToJson(data);
        string filePath = string.IsNullOrEmpty(fileName) ? dataPath : Path.Combine(Application.persistentDataPath, fileName + ".json");
        File.WriteAllText(filePath, jsonData);

        if(typeof(T) == typeof(PlayerData))
        {
            playerData = data as PlayerData;
        }
    }

    // 데이터 불러오기
    public T LoadData<T>(string fileName = "")
    {
        string filePath = string.IsNullOrEmpty(fileName) ? dataPath : Path.Combine(Application.persistentDataPath, fileName + ".json");
        // 저장된 파일이 있을 때
        if(File.Exists(filePath))
        {
            string jsonData = File.ReadAllText(filePath);
            return JsonUtility.FromJson<T>(jsonData);
        }
        // 저장된 파일이 없을 때
        else
        {
            return default(T); 
        }
    }

    // 플레이어 데이터에 대한 접근자 메서드
    public PlayerData GetPlayerData()
    {
        return playerData;
    }

}
  • 기본적으로 데이터가 저장될 위치는 /Assets/Data 폴더 아래로 설정했습니다.
  • 게임시작시 불러올 데이터가 있는지 확인하고, 있다면 데이터를 가져오도록하였습니다.
  • 데이터의 저장 및 불러오기를 하고싶을때는 DataManager의 인스턴스에 접근하여 SaveData, LoadData 함수를 이용하면 됩니다.
  • 플레이어 데이터에 접근할 수 있도록 GetPlayerData() 함수를 통해 다른스크립트에서 PlayerData에 접근할 수 있습니다.

기존코드 수정

이렇게 바꿈으로써 기존의 PlayerInfo를 참조하고있던 다른 스크립트에 문제가 생기게됩니다.

먼저 PlayerInfo를 참조하던 스크립트는 UIPlayerStats, PlayerController가 있습니다.

[SerializeField] 속성을 통해 PlayerInfo를 참조하던 부분을 제거하고, 아래와 같은 방식으로 PlayerData에 접근하도록합니다.

private PlayerData playerData;

private void Start()
{
    // PlayerData에 접근
    playerData = DataManager.Instance.GetPlayerData();
}

이제 PlayerData의 멤버변수에 접근할 수 있습니다.

하지만 그 값을 직접 수정할수는 없습니다.

변수의 값을 수정하기위해서는 PlayerData 클래스의 ModifyPlayerCurHp() 함수와 같이 변수값을 수정할 수 있는 함수를 제공해야합니다.

댓글남기기