Używanie PlayerPrefs do odczytu i zapisu danych

Strona zaktualizowana :
Data utworzenia strony :

Środowisko weryfikacji

Windows
  • Okna 11
Edytor Unity
  • 2021.3.3f1
Pakiet systemu wejściowego
  • 1.3.0

Wymagania wstępne dotyczące tej porady

Poniższe ustawienia zostały wcześniej wprowadzone jako przesłanka do opisu tej wskazówki.

Na początku

Jeśli graliście w gry, większość z was tego doświadczyła. Prawdopodobnie wstrzymałeś grę i zapisałeś lub załadowałeś dane gry, aby ją przerwać.

Podczas tworzenia gry zwykle musisz utworzyć tę funkcję zapisywania i ładowania, ustawić opcje itp. Tutaj postaramy się to osiągnąć za pomocą najprostszego PlayerPrefs sposobu przechowywania i ładowania danych.

Umiejscowienie interfejsu użytkownika

Tutaj spróbujemy zapisać lub odczytać zawartość wejściową, umieszczając elementy wejściowe i przyciski i klikając przycisk. Na razie potrzebujesz tylko co najmniej dwóch przycisków i jednego pola wprowadzania, więc możesz je umieścić.

Przygotowanie do przetwarzania interfejsu użytkownika

Najpierw zaimplementujmy przycisk zapisz. Jak utworzyć zdarzenie przycisku jest przedstawione w poniższych wskazówkach, więc wymienię tylko odpowiednie części.

Pozostaw nazwę ButtonEvent skryptu jako .

Skrypt wygląda tak:

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()
  {
  }
}

Ponieważ konieczne jest pobranie lub ustawienie wprowadzonej wartości, przygotuj ją jako pole. Dołącz również metodę, która będzie wywoływana po kliknięciu każdego przycisku.

Dołącz skrypt EventSystem do każdego pola wejściowego i ustaw je. Może to być dowolny obiekt, który chcesz dołączyć.

Ustaw każdą metodę, która ma być wywoływana po kliknięciu przycisku.

Zapisz wartość

Teraz, gdy metoda jest wywoływana po OnClickSave kliknięciu przycisku zapisywania, proces przycisku zapisu jest następujący.

/// <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 Metoda jest ustawiona na klucz i wartość do zapisania. Klucz jest określany podczas ładowania zapisanych danych. SetString Tutaj wywołujemy metodę, ponieważ wartość, która ma być przechowywana, jest ciągiem znaków. int float Jeśli chcesz SetInt zapisać wartość innego typu, taką jak i , istnieją metody, takie jak i SetFloat , więc nazwij je zgodnie z typem.

PlayerPrefs.Save Na koniec wywołaj metodę, aby potwierdzić zapisanie. W rzeczywistości można go zapisać, nawet jeśli nie wywołasz tej metody, ale bezpieczniej jest ją nazwać.

Jednak nawet jeśli uruchomisz grę w tym momencie, zapisze ona tylko wartość, więc nie będziesz wiedział, czy została poprawnie zapisana. Jeśli sprawdzisz zapisaną lokalizację, możesz zobaczyć dane, ale ...

Uzyskaj zapisaną wartość

Następnie zaimplementuj proces ładowania zapisanych danych. Przetwarzanie przycisku jest takie samo jak proces zapisywania, więc tylko kod procesu ładowania jest tutaj opisany.

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

Użyj metody, aby PlayerPrefs.GetString załadować zapisane dane. Wartość zapisaną z tym kluczem można uzyskać, określając klucz określony w polu Zapisz jako argument. Wartość jest pobierana w zwracanej wartości metody.

Jest to również zapisywane jako ciąg w taki sam sposób, jak podczas zapisywania, więc GetString nazywamy metodę. int float Jeśli zapisujesz GetIntGetFloat za pomocą lub , wywołaj metodę.

Pobrana wartość zostanie odzwierciedlona w polu wejściowym.

Teraz możesz zapisać i załadować dane. Myślę, że nie ma żadnych trudnych elementów.

Spróbuj go przenieść

Uruchom, aby wejść, zapisać i załadować. Zapisane dane są zachowywane i powinno być możliwe załadowanie nawet po wyjściu i ponownym uruchomieniu gry. Jeśli możesz potwierdzić następujący wzór, myślę, że nie ma problemu.

  1. Wprowadź wartość
  2. Kliknij w przycisk zapisywania
  3. Zmienianie wprowadzonej wartości
  4. Kliknij przycisk importowania, aby potwierdzić, że powraca zapisana wartość.
  5. Wyjdź z gry
  6. Uruchom ponownie grę i kliknij przycisk ładowania, aby sprawdzić, czy możesz przywołać zapisaną wartość
  7. Wprowadź inną wartość, zapisz ją i sprawdź, czy możesz odczytać ją ze zaktualizowaną wartością

Zapisywanie i ładowanie fragmentu danych

W próbce do tej pory zapisano tylko kilka parametrów. W miarę tworzenia gry liczba parametrów do zapisania będzie stale rosła, a jeśli przeczytasz i napiszesz je jeden po drugim, kod będzie ogromny. Dlatego podczas tworzenia danych, które mają być faktycznie zapisane, teoria polega na połączeniu danych, które mają zostać zapisane w jeden, a następnie zapisaniu ich wszystkich naraz.

Najpierw utwórz strukturę danych zapisu jako klasę. Celem jest możliwość jednoczesnego odczytu i zapisu danych, ale także klasyfikowanie danych w celu ułatwienia kodowi dostępu do każdego fragmentu danych.

Poniżej przedstawiono przykłady klas zapisu gry: Można go napisać w dowolnym miejscu, można się do niego odwołać z innego kodu. Ta struktura klas jest przykładowa, więc w prawdziwej grze musisz ją stworzyć dla swojej gry.

/// <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 W standardowej funkcji Unity używanej tym razem, jeśli zdefiniujesz tablice lub masz wiele unikatowych klas, System.Serializable Jeśli nie dodasz atrybutu, nie zostanie on poprawnie przekonwertowany, więc Character ustawiam atrybut na klasęSerializable.

Po utworzeniu klasy utwórz dane do zapisania. Oczywiście możesz mieć instancje tej klasy w całej grze. To zależy od tego, jak gra jest wykonana.

// 保存するデータ作成
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, },
  },
};

Po ustawieniu JsonUtility.ToJson danych w instancji klasy, przekonwertuj (serializuj) je na ciąg JSON za pomocą metody. Ponieważ wartość obiektu jest pojedynczym "ciągiem" zwanym JSON ze strukturą danych, wszystkiePlayerPrefs.SetString dane można zapisać za pomocą jednego wywołania metody.

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

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

Ponieważ jednak wszystkie dane są gromadzone w jednym, nie jest możliwe zapisanie tylko jego części lub odczytanie tylko części. Dlatego lepiej jest uczynić go jednostką, która jest łatwa do podsumowania, na przykład łącząc ją jako jeden obiekt dla jednego zapisu danych.

Podczas odczytu zapisanych danych możesz wykonać przetwarzanie odwrotne podczas zapisywania. Dane, które mają zostać odczytane, to pojedynczy ciąg, ale zawartość to struktury danych w formacie JSON, więc JsonUtility.FromJson można je konwertować (deserializować) na instancje klas za pomocą metod. Ponieważ jednak nie FromJson mamy informacji w ciągu, na jaką klasę konwertować, musimy określić typ podczas wywoływania metody.

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

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

Jeśli spróbujesz go przenieść, zobaczysz, że jest poprawnie zapisany i można go załadować.

Nawiasem mówiąc, tym razem używamy standardowych JsonUtility klas Unity, ale mogą one nie być w stanie konwertować klas ze złożonymi strukturami danych, ponieważ nie są zbyt funkcjonalne. W takim przypadku zaleca się korzystanie z innych bibliotek.

Gdzie są przechowywane dane?

PlayerPrefs Gdy używasz klasy do przechowywania danych, lokalizacja, w której są zapisywane, zależy od platformy, na której działasz. Zapoznaj się z oficjalną stroną poniżej, aby dowiedzieć się, gdzie jest on faktycznie przechowywany.

W niektórych środowiskach, takich jak system Windows, nie są one przechowywane w pliku, ale w ustawieniach systemowych, takich jak rejestr. Ponieważ nie jest to plik, nie nadaje się do zapisywania zapisanych danych w programie , na przykład jeśli zapisane dane są bardzo duże lub PlayerPrefs chcesz zsynchronizować zapisane dane z innym środowiskiem. I odwrotnie, jeśli dane do zapisania mają rozmiar poziomu opcji lub jeśli jest to samodzielna gra, która jest ukończona tylko w środowisku, w którym jest uruchomiona, myślę, że możliwe jest PlayerPrefs zapisanie danych w .

Ponadto na ścieżkę zapisanej lokalizacji mogą mieć wpływ ustawienia "CompanyName" i "ProductName". Jeśli chcesz opublikować swoją grę, musisz zdecydować się na te wartości z dużym wyprzedzeniem i nie zmieniać ich po opublikowaniu gry.

Informacje o szyfrowaniu danych

Przechowywane dane nie są automatycznie szyfrowane. Jeśli umiejętności gracza zostaną zapisane w niezmienionej postaci, użytkownik dowolnie przepisze wartości, co wpłynie na grę.

Czy musisz szyfrować, a jeśli tak, to jaki poziom siły jest wymagany i jak obsługiwać klucz szyfrowania? Rzeczy do rozważenia różnią się w zależności od gry.

Nie wyjaśnię tutaj metody szyfrowania, ale jeśli sprawdzisz to w Internecie, jest to główny język i narzędzie, więc myślę, że istnieją różne metody. Na razie, jeśli nie rozumiesz znaczenia przechowywanych treści, nawet jeśli otworzysz plik, i jeśli źle manipulujesz danymi, nie będziesz mógł korzystać z zapisanych danych, myślę, że będzie pewien efekt zapobiegający oszustwom.