Използване на PlayerPrefs за четене и запис на данни

Страницата се актуализира :
Дата на създаване на страница :

Среда за проверка

Уиндоус
  • Прозорци 11
Редактор на единство
  • 2021.3.3f1
Пакет на входната система
  • 1.3.0

Предпоставки за този съвет

Следните настройки са направени предварително като предпоставка за описанието на този съвет.

Отначало

Ако сте играли игри, повечето от вас са го преживели. Вероятно сте поставили на пауза дадена игра и сте запазили или заредили данните си за игра, за да ги оставите.

Когато създавате игра, обикновено трябва да създадете тази функция за запазване и зареждане, да зададете опции и т.н. Тук ще се опитаме да постигнем това, като използваме най-простия PlayerPrefs начин за съхранение и зареждане на данни.

Разположение на потребителския интерфейс

Тук ще се опитаме да запазим или прочетем входното съдържание, като поставим входните елементи и бутони и щракнем върху бутона. За момента се нуждаете само от поне два бутона и едно поле за въвеждане, така че не се колебайте да ги поставите.

Подготовка за обработка на потребителския интерфейс

Първо, нека внедрим бутона за запазване. Как да създадете събитие с бутон е въведено в следващите съвети, така че ще изброя само съответните части.

Оставете името 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 ние наричаме метода. int float Ако записвате GetIntGetFloat с или , обадете се на метода.

Извлечената стойност се отразява във входното поле.

Сега можете да запазвате и зареждате данните. Не мисля, че има някакви трудни елементи.

Опитайте да го преместите

Стартирайте, за да влезете, запишете и заредите. Запазените данни се запазват и трябва да могат да се зареждат, дори ако излезете и стартирате отново играта. Ако можете да потвърдите следния модел, мисля, че няма проблем.

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

В стандартната List функция Unity, използвана този път, ако дефинирате масиви или имате няколко уникални класа, 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 класове на Unity, но те може да не успеят да преобразуват класове със сложни структури от данни, защото не са много функционални. В този случай се препоръчва използването на други библиотеки.

Къде се съхраняват данните?

PlayerPrefs Когато използвате клас за съхраняване на данни, местоположението, където се записват, зависи от платформата, на която работите. Моля, вижте официалната страница по-долу за това къде всъщност се съхранява.

В някои среди, като например Windows, те не се съхраняват във файл, а в системни настройки, като например системния регистър. Тъй като не е файл, той не е подходящ за записване на записани данни в , например, ако записаните данни са много големи или PlayerPrefs искате да синхронизирате записаните данни с друга среда. Обратно, ако данните, които трябва да бъдат запазени, са с размера на нивото на опцията, или ако това е самостоятелна игра, която е завършена само в средата, в която се изпълнява, мисля, че е PlayerPrefs възможно да запазите данните в .

Освен това пътят на запазеното местоположение може да бъде повлиян от настройките "CompanyName" и "ProductName". Ако искате да публикувате играта си, трябва предварително да вземете решение за тези стойности и да не ги променяте, след като публикувате играта си.

За шифроването на данни

Съхранените данни не се криптират автоматично. Ако способностите на играча са запазени такива, каквито са, потребителят свободно ще пренапише стойностите, което ще повлияе на играта.

Трябва ли да шифровате и ако е така, какво ниво на сила се изисква и как се справяте с ключа за криптиране? Нещата, които трябва да се вземат предвид, варират от игра до игра.

Няма да обяснявам метода за криптиране тук, но ако го потърсите в интернет, това е основен език и инструмент, така че мисля, че има различни методи. За момента, ако не разбирате смисъла на съхраненото съдържание дори и да отворите файла, и ако подправяте данните лошо, няма да можете да използвате запазените данни, мисля, че ще има някакъв ефект срещу измамите.