[Unity] 세이브 로드 마이그레이션
본문 로딩 중...
댓글 0
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요!
게임에 있어서 세이브 로드 기능은 빠질 수가 없는 요소다
게임의 진행 상황을 저장하고 불러오며 버전에 따라 데이터를 마이그레이션 하는 코드를 연습해봤다.
using System.Collections.Generic;
using UnityEngine;
public abstract class SaveData
{
public int Version { get; set; }
public abstract SaveData VersionUp();
}
public class SaveDataV1 : SaveData
{
public int CurrentDay { get; set; } = 1;
public int HungerEmptyCount { get; set; } = 0;
public int CurrentHp { get; set; } = 100;
public SaveDataV1()
{
Version = 1;
}
public override SaveData VersionUp()
{
return new SaveDataV2
{
Version = 2,
CurrentDay = CurrentDay,
HungerEmptyCount = HungerEmptyCount,
CurrentHp = CurrentHp,
Inventory = new(),
Storage = new(),
};
}
}
public class SaveDataV2 : SaveDataV1
{
public List<SaveSlotData> Inventory { get; set; } = new();
public List<SaveSlotData> Storage { get; set; } = new();
public SaveDataV2()
{
Version = 2;
}
public override SaveData VersionUp()
{
return new SaveDataV3
{
Version = 3,
CurrentDay = CurrentDay,
HungerEmptyCount = HungerEmptyCount,
CurrentHp = CurrentHp,
Inventory = Inventory,
Storage = Storage,
TributeLevel = 0,
CurrentTributeLevel = 0,
TributeRequirementID = "",
TributeSubmitted = new(),
};
}
}
public class SaveDataV3 : SaveDataV2
{
public int TributeLevel { get; set; } = 0;
public int CurrentTributeLevel { get; set; } = 0;
public string TributeRequirementID { get; set; } = "";
public List<int> TributeSubmitted { get; set; } = new();
public SaveDataV3()
{
Version = 3;
}
public override SaveData VersionUp()
{
return this;
}
}
저장할 데이터 구조 정의 버전별로 클래스를 분리해 관리하며, 구 버전 세이브 파일을 최신 버전으로 자동 변환하는 VersionUp() 메서드를 포함한다.
using System.IO;
using Newtonsoft.Json;
using UnityEngine;
using SaveDataVC = SaveDataV5;
public static class SaveLoadManager
{
public enum SaveMode
{
Text, // .json
Encrypted, // .dat
}
public static SaveMode Mode { get; set; } = SaveMode.Text; // 여기서 모드 전환
private static readonly int SaveDataVersion = 5;
private static readonly string SaveDirectory = Path.Combine(
Application.persistentDataPath,
"Save"
);
private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.All,
};
public static SaveDataVC Data { get; set; } = new SaveDataVC();
private static string SaveFilePath =>
Mode == SaveMode.Text
? Path.Combine(SaveDirectory, "SaveAuto.json")
: Path.Combine(SaveDirectory, "SaveAuto.dat");
public static void Init()
{
Load();
}
public static bool Save()
{
if (Data == null)
return false;
try
{
if (!Directory.Exists(SaveDirectory))
Directory.CreateDirectory(SaveDirectory);
string json = JsonConvert.SerializeObject(Data, Settings);
if (Mode == SaveMode.Text)
File.WriteAllText(SaveFilePath, json);
else
File.WriteAllBytes(SaveFilePath, CryptoUtil.Encrypt(json));
return true;
}
catch
{
Debug.LogError("[SaveLoadManager] Save 실패");
return false;
}
}
public static bool Load()
{
if (!File.Exists(SaveFilePath))
return false;
try
{
string json;
if (Mode == SaveMode.Text)
json = File.ReadAllText(SaveFilePath);
else
json = CryptoUtil.Decrypt(File.ReadAllBytes(SaveFilePath));
SaveData saveData = JsonConvert.DeserializeObject<SaveData>(json, Settings);
while (saveData.Version < SaveDataVersion)
saveData = saveData.VersionUp();
Data = saveData as SaveDataVC;
return true;
}
catch
{
Debug.LogError("[SaveLoadManager] Load 실패");
return false;
}
}
public static bool HasSaveData()
{
return File.Exists(SaveFilePath);
}
public static void DeleteSave()
{
if (File.Exists(SaveFilePath))
File.Delete(SaveFilePath);
Data = new SaveDataVC();
}
}
실제 저장/불러오기 처리 JSON 또는 암호화 파일로 저장하고, 로드 시 버전 마이그레이션까지 자동으로 수행한다.
저장 모드 Text(.json)와 Encrypted(.dat) 두 가지 모드를 지원하며, Mode 값 하나로 전환
Save() 현재 Data를 JSON으로 직렬화한 뒤, 모드에 따라 그대로 저장하거나 암호화해서 저장
Load() 파일을 읽어 역직렬화한 뒤, 버전이 낮으면 VersionUp()을 반복 호출해 최신 버전으로 변환하고, 구버전 세이브 파일도 정상적으로 불러옴
그 외 HasSaveData()로 세이브 파일 존재 여부를 확인하고, DeleteSave()로 초기화할 수 있습니다.