使用播放機首選項讀取和寫入數據

更新頁 :
頁面創建日期 :

驗證環境

窗戶
  • 視窗 11
統一編輯器
  • 2021.3.3f1
輸入系統包
  • 1.3.0

此提示的先決條件

作為此提示描述的前提,已預先進行了以下設置。

起先

如果你玩過遊戲,你們中的大多數人都經歷過。 您可能已暫停遊戲並儲存或載入遊戲資料以將其關閉。

創建遊戲時,通常需要創建此保存和載入功能,設置選項等。 在這裡,我們將嘗試使用最簡單的 PlayerPrefs 方法來存儲和載入數據來實現這一點。

用戶介面放置

在這裡,我們將嘗試通過放置輸入項和按鈕並按下按鈕來保存或讀取輸入內容。 目前,您只需要至少兩個按鈕和一個輸入字段,因此請隨意放置它們。

準備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 如果要 SetInt 保存其他類型的值,例如和 ,則有諸如 和 SetFloat 之類的方法,因此請根據類型調用它們。

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我們調用該方法。 intfloatGetIntGetFloat如果使用 或 保存,請調用該方法。

檢索到的值將反映在輸入欄位中。

您現在可以儲存和載入資料。 我認為沒有任何困難的元素。

嘗試移動它

運行以輸入、保存和載入。 保存的數據將保留,即使您退出並重新運行遊戲,也應該能夠載入。 如果您可以確認以下模式,我認為沒有問題。

  1. 輸入一個值
  2. 按下保存按鈕
  3. 更改您輸入的值
  4. 按兩下匯入按鈕以確認它返回到保存的值。
  5. 退出遊戲
  6. 重新運行遊戲並按下載入按鈕以查看是否可以調用保存的值
  7. 輸入不同的值,保存它,然後檢查是否可以使用更新的值讀取相同的值

保存和載入數據塊

在到目前為止的示例中,僅保存了幾個參數。 當你實際製作一個遊戲時,要保存的參數數量會穩步增加,如果你一個一個地讀寫它們,代碼將是巨大的。 因此,在創建要實際保存的數據時,理論是將要保存的數據合併為一個,然後一次全部寫入。

首先,將數據結構保存為類。 目標是能夠一次讀取和寫入數據,但也對數據進行分類,以使代碼更容易訪問每段數據。

以下是儲存遊戲類的範例: 它可以寫在任何可以從其他代碼引用的地方。 此類結構是一個範例,因此在實際遊戲中,您需要為遊戲創建它。

/// <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;
}

在這次使用的 Unity 標準函數中 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);

如果您嘗試移動它,您可以看到它已正確保存並且可以載入。

順便說一下,我們這次使用的是 Unity 標準 JsonUtility 類,但它們可能無法轉換具有複雜數據結構的類,因為它們的功能不是很好。 在這種情況下,建議使用其他庫。

數據存儲在哪裡?

PlayerPrefs 使用類存儲數據時,保存數據的位置取決於運行數據的平臺。 請參閱下面的官方頁面,瞭解實際存儲的位置。

在某些環境(如 Windows)中,它們不存儲在檔中,而是存儲在註冊表等系統設置中。 由於它不是檔,因此不適合將保存的數據保存在 中,例如,如果保存的數據非常大,或者 PlayerPrefs 您希望將保存數據與另一個環境同步。 相反,如果要保存的數據是選項級別的大小,或者如果它是僅在運行環境中完成的獨立遊戲, PlayerPrefs 我認為可以將數據保存在.

此外,保存位置的路徑可能會受到「公司名稱」和「產品名稱」設置的影響。 如果要發佈遊戲,則需要提前確定這些值,並且在發佈遊戲后不要更改它們。

關於數據加密

存儲的數據不會自動加密。 如果玩家的能力按原樣保存,使用者將自由重寫值,這將影響遊戲。

您是否需要加密,如果需要,需要什麼級別的強度,以及如何處理加密密鑰? 要考慮的事情因遊戲而異。

我不會在這裡解釋加密方法,但是如果你在互聯網上查找它,它是一種主要的語言和工具,所以我認為有多種方法。 目前,如果您即使打開檔也不瞭解存儲內容的含義,並且如果篡改數據不佳,您將無法使用保存的數據,我認為會有一些反欺詐效果。