using UnityEngine;
public interface ISaveManager
{
public void SaveGame(ref GameData _data);
public void LoadGame(GameData _data);
}
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class SaveManager : MonoBehaviour
{
[SerializeField] private string fileName;
[SerializeField] private bool encryptData;
private GameData gameData;
private FileDataHandler fileHandler;
private void Awake()
{
DontDestroyOnLoad(gameObject);
if (instance != null)
{
Destroy(instance.gameObject);
}
else
instance = this;
}
private void Start()
{
fileHandler = new FileDataHandler(Application.persistentDataPath, fileName, encryptData);
gameData = new GameData();
Load();
}
private void Save()
{
foreach (var saveManager in GetISaveManagers())
{
saveManager.SaveGame(ref gameData);
}
fileHandler.Save(gameData);
}
private void Load()
{
gameData = fileHandler.Load();
if(this.gameData == null)
gameData = new GameData();
foreach (var saveManager in GetISaveManagers())
{
saveManager.LoadGame(gameData);
}
}
private void OnApplicationQuit()
{
Save();
}
[ContextMenu("Delete Save Data")]
private void DeleteSaveData()
{
fileHandler.DeleteFile();
}
private List<ISaveManager> GetISaveManagers()
{
IEnumerable<ISaveManager> saveManagers = FindObjectsByType<MonoBehaviour>(FindObjectsSortMode.None).OfType<ISaveManager>();
return new List<ISaveManager>(saveManagers);
}
}
하이어라키에 존재하는 세이브를 하는 객체이다.
FileDataHandler를 생성하며 가지고있다. 즉 세이브/로드를 하고 파일을 생성/로드 같은 작업들이 이 객체에서 이루어진다.
FileDataHandler생성자로 인자값으로 기본경로, 파일이름, 암호화 여부를 넘긴다.
✧ Save
✧ Load
✧ GetISaveManagers
using System;
using System.IO;
using TMPro;
using UnityEngine;
public class FileDataHandler
{
private string dataPath;
private string dataFileName;
private bool encryptData = false;
private string codeWord = "hsd";
public FileDataHandler(string _dataPath, string _dataFileName, bool _encryptData)
{
dataFileName = _dataFileName;
dataPath = _dataPath;
encryptData = _encryptData;
}
public void Save(GameData _data)
{
string fullPath = Path.Combine(dataPath, dataFileName);
try
{
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
string dataToStore = JsonUtility.ToJson(_data, true);
using (FileStream stream = new FileStream(fullPath, FileMode.Create))
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.Write(dataToStore);
}
}
if (encryptData)
dataToStore = EncryptDecrypt(dataToStore);
}
catch (Exception e)
{
Debug.LogError($"Error : {fullPath}에 세이브 되지 않았습니다. {e}");
}
}
public GameData Load()
{
string fullPath = Path.Combine(dataPath, dataFileName);
GameData loadData = null;
if (File.Exists(fullPath))
{
try
{
string dataToLoad = "";
using (FileStream stream = new FileStream(fullPath, FileMode.Open))
{
using (StreamReader reader = new StreamReader(stream))
{
dataToLoad = reader.ReadToEnd();
}
}
if(encryptData)
dataToLoad = EncryptDecrypt(dataToLoad);
loadData = JsonUtility.FromJson<GameData>(dataToLoad);
}
catch (Exception e)
{
Debug.LogError($"Error : {fullPath}에 로드 되지 않았습니다. {e}");
}
}
return loadData;
}
public void DeleteFile()
{
string fullPath = Path.Combine(dataPath, dataFileName);
if (File.Exists(dataPath))
File.Delete(dataPath);
}
private string EncryptDecrypt(string _data)
{
string modifiedData = "";
for (int i = 0; i < _data.Length; i++)
{
modifiedData += (char)(_data[i] & codeWord[i % codeWord.Length]);
}
return modifiedData;
}
}
fullPath
그 후 fullPath의 파일 경로만 가져온다.
✧ dataToStore
✧ FileStream
✧ StreamWriter
✧ try
✧ catch