저희 게임은 무기를 먹으면 해금이 되는 시스템입니다. 저장기능을 만들면서 저장에 필요한 데이터들이 많지 않은것을 깨닫고 PlayerPrefs를 사용하여 저장을 만들기로 하였습니다.
PlayerPrefs
Unity에서 제공하는 간단한 데이터 저장 시스템으로, 간단한 키-값 쌍을 저장하고 불러올 수 있음.
기본적으로 int, float, string 데이터 타입을 저장할 수 있음.
간단한 데이터 저장에 적합하며, 민감한 데이터나 보안이 중요한 데이터에는 사용하지 않는 것이 좋음.
데이터는 폴더 내에 플레인 텍스트로 저장되기 때문에 안전하지 않을 수 있음.
사용법
데이터 저장
PlayerPrefs.SetInt("SectorCount", saveData.sectorCount); PlayerPrefs.SetInt("PlayerHP", saveData.playerHP); string saveDataJson = saveData.Serialize(); PlayerPrefs.SetString("SaveData", saveDataJson); PlayerPrefs.Save();
SectorCount와 PlayerHP라는 키로 Int형 데이터를 저장, Save 메서드를 호출하여 변경사항을 저장.
데이터 불러오기:
saveData.sectorCount = PlayerPrefs.GetInt("SectorCount", 0); saveData.playerHP = PlayerPrefs.GetInt("PlayerHP", 1 string saveDataJson = PlayerPrefs.GetString("SaveData", "{}"); saveData = SaveData.Deserialize(saveDataJson);
Get 메서드를 사용하여 저장된 값을 불러올 수 있음.
두 번째 인자는 기본값으로 사용됨.
만약 해당 키에 저장된 값이 없으면 기본값이 반환.
데이터 삭제 예시
PlayerPrefs.DeleteKey("Score"); // "Score" 키와 연결된 데이터 삭제 PlayerPrefs.DeleteAll(); // 모든 데이터 삭제 PlayerPrefs.Save(); // 변경사항 저장
DeleteKey 메서드를 사용하여 특정 키와 연결된 데이터를 삭제할 수 있고, DeleteAll 메서드를 사용하여 모든 데이터를 삭제할 수 있음.
SaveData
sectorCount, playerHP, playerPosition,unlockedWeapons등의 저장해야 될 데이터들을 가지고 있음.
GunData나 Vector3 같은 데이터를 직렬화, 역직렬화 하기 위해 Serialize, Deserialize 메서드를 정의.
이 직렬화와 역직렬화를 위해 SaveDataWrapper클래스를 따로 정의하여 SaveData 객체의 일부 데이터를 변환하여 저장하고, 그 반대로 역변환하는 역할을 수행.
코드
[Serializable] public class SaveData { [Header("Sector Data")] public int sectorCount; [Header("Player Status")] public int playerHP; public Vector3 playerPosition; [Header("Unlocked Weapons")] public List<GunType> unlockedWeapons = new List<GunType>(); public List<GunType> UnlockedWeapons { get { return unlockedWeapons; } } // 직렬화 함수 public string Serialize() { SaveDataWrapper wrapper = new SaveDataWrapper(this); return JsonUtility.ToJson(wrapper); } // 역직렬화 함수 public static SaveData Deserialize(string json) { SaveDataWrapper wrapper = JsonUtility.FromJson<SaveDataWrapper>(json); return wrapper.ToSaveData(); } [Serializable] private class SaveDataWrapper { public List<string> unlockedWeapons; public float[] playerPosition; public SaveDataWrapper(SaveData saveData) { unlockedWeapons = saveData.UnlockedWeapons.ConvertAll(gunType => gunType.ToString()); playerPosition = new float[] { saveData.playerPosition.x, saveData.playerPosition.y, saveData.playerPosition.z }; } public SaveData ToSaveData() { SaveData saveData = new SaveData(); saveData.UnlockedWeapons.Clear(); foreach (string gunTypeString in unlockedWeapons) { if (Enum.TryParse(gunTypeString, out GunType gunType)) { saveData.UnlockedWeapons.Add(gunType); } } if (playerPosition != null && playerPosition.Length == 3) { saveData.playerPosition = new Vector3(playerPosition[0], playerPosition[1], playerPosition[2]); } return saveData; } } }
SaveDataWrapper 생성자
SaveData → SaveDataWrapper: SaveData 객체를 받아서 필요한 형태로 변환.
unlockedWeapons를 List으로 변환하고, playerPosition을 float 배열로 변환.
ToSaveData 메서드
SaveDataWrapper → SaveData: SaveDataWrapper 객체를 받아 다시 원래의 SaveData 객체로 역변환.
List을 다시 List으로 변환하고, float 배열을 다시 Vector3로 변환