PlayerPrefs를 사용하여 데이터 읽기 및 쓰기

페이지 업데이트 :
페이지 생성 날짜 :

검증 환경

윈도우
  • 윈도우 11
Unity 에디터
  • 2021.3.3f1
입력 시스템 패키지
  • 1.3.0

이 팁의 전제 조건

이 팁에 대한 설명의 전제로 다음 설정이 미리 이루어졌습니다.

처음에

게임을 해본 사람이라면 대부분 경험해 보셨을 것입니다. 게임을 일시중지하고 플레이 데이터를 저장하거나 로드하여 중단한 적이 있을 수 있습니다.

게임을 만들 때 일반적으로 이 저장 및 로드 기능을 만들고 옵션을 설정하는 등의 작업을 수행해야 합니다. 여기에서는 데이터를 저장하고 로드하는 가장 간단한 PlayerPrefs 방법을 사용하여 이를 달성하려고 합니다.

UI 배치

여기에서는 입력 항목과 버튼을 배치하고 버튼을 클릭하여 입력 내용을 저장하거나 읽으려고 합니다. 당분간은 최소 2개의 버튼과 1개의 입력 필드만 필요하므로 자유롭게 배치하십시오.

UI 처리 준비

먼저 저장 버튼을 구현해 보겠습니다. 버튼 이벤트를 만드는 방법은 다음 팁에 소개되어 있으므로 관련 부분 만 나열하겠습니다.

스크립트 이름을 ButtonEvent 그대로 둡니다.

스크립트는 다음과 같습니다.

using UnityEngine;
using UnityEngine.UI;

public class ButtonEvent : MonoBehaviour
{
  /// <summary>名前入力フィールド。</summary>
  [SerializeField] InputField InputFieldName;

  /// <summary>HP 入力フィールド。</summary>
  [SerializeField] InputField InputFieldHP;

  /// <summary>攻撃力入力フィールド。</summary>
  [SerializeField] InputField InputFieldAttack;

  /// <summary>お金入力フィールド。</summary>
  [SerializeField] InputField InputFieldMoney;

  /// <summary>
  /// 保存ボタンをクリックしたときの処理。
  /// </summary>
  public void OnClickSave()
  {
  }

  /// <summary>
  /// 読み込みボタンをクリックしたときの処理。
  /// </summary>
  public void OnClickLoad()
  {
  }
}

입력한 값을 가져오거나 설정해야 하므로 필드로 준비합니다. 또한 각 단추를 클릭할 때 호출되는 메서드를 포함합니다.

스크립트를 첨부 EventSystem 하고 각 입력 필드를 설정합니다. 첨부하려는 모든 개체가 될 수 있습니다.

버튼을 클릭할 때 호출되는 각 메서드를 설정합니다.

값을 저장합니다

이제 저장 버튼을 클릭했을 때 OnClickSave 메서드가 호출되었으니, 저장 버튼의 과정은 다음과 같습니다.

/// <summary>
/// 保存ボタンをクリックしたときの処理。
/// </summary>
public void OnClickSave()
{
  // 各値を指定したキーに保存します
  PlayerPrefs.SetString("Name", InputFieldName.text);
  PlayerPrefs.SetString("HP", InputFieldHP.text);
  PlayerPrefs.SetString("Attack", InputFieldAttack.text);
  PlayerPrefs.SetString("Money", InputFieldMoney.text);

  // 設定したデータを確定して保存します
  PlayerPrefs.Save();
}

PlayerPrefs.SetString 메서드는 저장할 키와 값으로 설정됩니다. 키는 저장된 데이터를 로드할 때 지정됩니다. SetString 여기서는 저장할 값이 문자열이기 때문에 메서드를 호출합니다. int float 및 와 같은 다른 유형의 값을 저장하려면 SetIntSetFloat 와 같은 메소드가 있으므로 유형에 따라 호출하십시오.

PlayerPrefs.Save 마지막으로 메서드를 호출하여 저장을 확인합니다. 사실 이 메서드를 호출하지 않아도 저장될 수 있지만 호출하는 것이 더 안전합니다.

다만, 이 시점에서 게임을 실행해도 값만 저장되기 때문에 제대로 저장되었는지 알 수 없습니다. 저장된 위치를 확인하면 데이터를 볼 수 있지만...

저장된 값 가져오기

다음으로 저장된 데이터를 로드하는 프로세스를 구현합니다. 버튼의 처리는 저장 과정과 동일하므로 여기서는 로딩 과정의 코드만 설명합니다.

/// <summary>
/// 読み込みボタンをクリックしたときの処理。
/// </summary>
public void OnClickLoad()
{
  // 指定したキーから値を読み込みます
  InputFieldName.text = PlayerPrefs.GetString("Name");
  InputFieldHP.text = PlayerPrefs.GetString("HP");
  InputFieldAttack.text = PlayerPrefs.GetString("Attack");
  InputFieldMoney.text = PlayerPrefs.GetString("Money");
}

이 방법을 PlayerPrefs.GetString 사용하여 저장된 데이터를 로드합니다. 인수로 저장에 지정된 키를 지정하여 해당 키와 함께 저장된 값을 가져올 수 있습니다. 이 값은 메서드의 반환 값에서 검색됩니다.

이것도 저장할 때와 같은 방식으로 문자열로 저장되므로 GetString 메서드를 호출합니다. intGetFloat GetIntfloat 또는 를 사용하여 저장하는 경우 메서드를 호출합니다.

검색된 값은 입력 필드에 반영됩니다.

이제 데이터를 저장하고 로드할 수 있습니다. 어려운 요소는 없다고 생각합니다.

이동해 보세요

실행하여 입력하고, 저장하고, 로드합니다. 저장된 데이터는 유지되며 게임을 종료하고 다시 실행하더라도 로드할 수 있어야 합니다. 다음과 같은 패턴을 확인할 수 있으면 문제 없다고 생각합니다.

  1. 값을 입력합니다
  2. 저장 버튼을 클릭합니다
  3. 입력한 값 변경
  4. 가져오기 버튼을 클릭하여 저장된 값으로 돌아가는지 확인합니다.
  5. 게임을 종료합니다
  6. 게임을 다시 실행하고 로드 버튼을 클릭하여 저장된 값을 불러올 수 있는지 확인합니다
  7. 다른 값을 입력하고 저장한 다음 업데이트된 값으로 동일한 값을 읽을 수 있는지 확인합니다

데이터 청크 저장 및 로드Save and load a chunk of data

지금까지 샘플에서는 몇 개의 매개 변수만 저장되었습니다. 실제로 게임을 만들다 보니 저장해야 할 파라미터의 개수가 꾸준히 늘어나고, 하나씩 읽고 쓰다 보면 코드가 엄청나게 됩니다. 따라서 실제로 저장할 데이터를 만들 때 이론은 저장할 데이터를 하나로 결합한 다음 한꺼번에 쓰는 것입니다.

먼저 저장 데이터 구조를 클래스로 만듭니다. 목표는 데이터를 한 번에 읽고 쓸 수 있을 뿐만 아니라 코드가 각 데이터에 더 쉽게 액세스할 수 있도록 데이터를 분류하는 것입니다.

다음은 저장 게임 클래스의 예입니다. 다른 코드에서 참조할 수 있는 모든 곳에서 작성할 수 있습니다. 이 클래스 구조는 샘플이므로 실제 게임에서는 게임용으로 만들어야 합니다.

/// <summary>セーブデータクラス。</summary>
public class SaveData
{
  public List<Character> Characters;
  public long Money;
}

/// <summary>1キャラクターの情報。</summary>
[Serializable]
public class Character
{
  public string Name;
  public int HP;
  public int Attack;
}

List 이번에 사용한 유니티 표준 함수에서 배열을 정의하거나 여러 개의 고유 클래스가 있는 경우, System.Serializable 속성을 추가하지 않으면 올바르게 Character 변환되지 않으므로 속성을 클래스로 Serializable 설정했습니다.

클래스를 만든 후 저장할 데이터를 만듭니다. 물론 게임 전반에 걸쳐 이 클래스의 인스턴스를 가질 수 있습니다. 이것은 게임이 어떻게 만들어지는지에 달려 있습니다.

// 保存するデータ作成
var saveData = new SaveData
{
  Money = 10000,
  Characters = new List<Character>
  {
    new Character { Name= "レイシア", HP = 50, Attack = 40, },
    new Character { Name= "アイリ", HP = 56, Attack = 27, },
    new Character { Name= "ニール", HP = 72, Attack = 36, },
    new Character { Name= "トリー", HP = 61, Attack = 30, },
  },
};

클래스의 인스턴스에서 데이터를 설정한 JsonUtility.ToJson 후 메서드를 사용하여 JSON 문자열로 변환(직렬화)합니다. 객체의 값은 데이터 구조를 가진 JSON이라는 단일 "문자열"이므로 모든 데이터는 메서드에 대한 단일 호출로 쓸PlayerPrefs.SetString 수 있습니다.

// オブジェクトを JSON 文字列に変換します
var saveJson = JsonUtility.ToJson(saveData);

// データを保存します
PlayerPrefs.SetString("SaveData", saveJson);
PlayerPrefs.Save();

그러나 모든 데이터가 하나로 수집되기 때문에 일부만 저장하거나 일부만 읽을 수는 없습니다. 따라서 하나의 저장 데이터에 대해 하나의 객체로 결합하는 것과 같이 요약하기 쉬운 단위로 만드는 것이 바람직합니다.

저장된 데이터를 읽을 때 저장할 때 역처리를 할 수 있습니다. 읽을 데이터는 단일 문자열이지만 내용은 JSON 형식의 데이터 구조이므로 JsonUtility.FromJson 메서드에 의해 클래스 인스턴스로 변환(역직렬화)할 수 있습니다. 그러나 문자열에 변환할 클래스에 대한 정보가 없기 FromJson 때문에 메서드를 호출할 때 형식을 지정해야 합니다.

// データを読み込みます
var loadJson = PlayerPrefs.GetString("SaveData");

// JSON 文字列からオブジェクトにデシリアライズします
var newData = JsonUtility.FromJson<SaveData>(loadJson);

이동을 시도하면 올바르게 저장되고로드 될 수 있음을 알 수 있습니다.

덧붙여서 이번에는 유니티 스탠다드 JsonUtility 클래스를 사용하고 있습니다만, 데이터 구조가 복잡한 클래스는 그다지 기능적이지 않기 때문에 변환하지 못할 수도 있습니다. 이 경우 다른 라이브러리를 사용하는 것이 좋습니다.

데이터는 어디에 저장되나요?

PlayerPrefs 클래스를 사용하여 데이터를 저장하는 경우 데이터가 저장되는 위치는 실행 중인 플랫폼에 따라 다릅니다. 실제 보관 위치는 아래 공식 페이지를 참조하십시오.

Windows와 같은 일부 환경에서는 파일에 저장되지 않고 레지스트리와 같은 시스템 설정에 저장됩니다. 파일이 아니기 때문에 에 저장 데이터를 저장하는 데는 적합하지 않습니다(예: 저장 데이터가 매우 크거나 PlayerPrefs 저장 데이터를 다른 환경과 동기화하려는 경우). 반대로, 저장하는 데이터가 옵션 레벨의 크기이거나, 실행중인 환경에서만 완성되는 독립형 게임이라면 에 데이터를 저장할 수 있다고 생각합니다 PlayerPrefs .

또한 저장된 위치의 경로는 "CompanyName" 및 "ProductName" 설정의 영향을 받을 수 있습니다. 게임을 퍼블리시하려면 이러한 값을 미리 결정하고 게임을 퍼블리싱한 후에는 변경하지 않아야 합니다.

데이터 암호화 정보

저장된 데이터는 자동으로 암호화되지 않습니다. 플레이어의 능력이 그대로 저장되면 사용자는 값을 자유롭게 다시 작성하여 게임에 영향을 미칩니다.

암호화해야 하며, 그렇다면 어느 수준의 강도가 필요하며, 암호화 키를 어떻게 처리합니까? 고려해야 할 사항은 게임마다 다릅니다.

암호화 방법은 여기서는 설명하지 않겠습니다만, 인터넷에서 찾아보면 주요 언어나 도구이기 때문에 여러가지 방법이 있다고 생각합니다. 당분간은 파일을 열어도 저장된 내용의 의미를 이해하지 못하고, 데이터를 잘못 조작하면 세이브 데이터를 사용할 수 없게되고, 사기 방지 효과가 있다고 생각합니다.