TIL (87) | 2023.11.28 | PlayerPrefs 와 JSON을 이용한 다양한 데이터 타입 저장

kjg5370·2023년 11월 28일
0

TIL

목록 보기
85/91
post-thumbnail

들어가기 앞서

저희 게임은 무기를 먹으면 해금이 되는 시스템입니다. 저장기능을 만들면서 저장에 필요한 데이터들이 많지 않은것을 깨닫고 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로 변환

profile
학생입니다

0개의 댓글