Brug PlayerPrefs til at læse og skrive data

Side opdateret :
Dato for oprettelse af side :

Miljø til bekræftelse

Windows
  • Windows 11
Enhedslistens redaktør
  • 2021.3.3f1
Input System Pakke
  • 1.3.0

Forudsætninger for dette tip

Følgende indstillinger er foretaget på forhånd som en forudsætning for beskrivelsen af dette tip.

Først

Hvis du har spillet spil, har de fleste af jer oplevet det. Du har sandsynligvis sat et spil på pause og gemt eller indlæst dine spildata for at holde det væk.

Når du opretter et spil, skal du normalt oprette denne gemme- og indlæsningsfunktion, indstille indstillinger osv. Her vil vi forsøge at opnå dette ved hjælp af den enkleste PlayerPrefs måde at gemme og indlæse data på.

Placering af brugergrænseflade

Her vil vi forsøge at gemme eller læse inputindholdet ved at placere inputelementerne og knapperne og klikke på knappen. I øjeblikket behøver du kun mindst to knapper og et indtastningsfelt, så du er velkommen til at placere dem.

Forberedelse til behandling af brugergrænsefladen

Lad os først implementere knappen Gem. Sådan oprettes en knapbegivenhed introduceres i de følgende tips, så jeg vil kun liste de relevante dele.

Lad scriptnavnet ButtonEvent være .

Scriptet ser sådan ud:

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

Da det er nødvendigt at hente eller indstille den indtastede værdi, skal du forberede den som et felt. Inkluder også den metode, der kaldes, når du klikker på hver knap.

Vedhæft dit EventSystem script til og indstil hvert inputfelt. Det kan være ethvert objekt, du vil vedhæfte.

Indstil hver metode, der skal kaldes, når der klikkes på knappen.

Gem værdien

Nu hvor metoden kaldes, når OnClickSave der klikkes på gem-knappen, er processen med gem-knappen som følger.

/// <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 Metoden er indstillet til en nøgle og en værdi, der skal gemmes. Nøglen angives, når de gemte data indlæses. SetString Her kalder vi metoden, fordi den værdi, der skal gemmes, er en streng. int float Hvis du vil SetInt gemme en værdi af en anden type, såsom og , er der metoder som og SetFloat , så kald dem i henhold til typen.

PlayerPrefs.Save Til sidst skal du ringe til metoden for at bekræfte gemningen. Faktisk kan det gemmes, selvom du ikke kalder denne metode, men det er sikrere at kalde det.

Men selvom du kører spillet på dette tidspunkt, gemmer det kun værdien, så du ved ikke, om det blev gemt korrekt. Hvis du kontrollerer den gemte placering, kan du se dataene, men ...

Få en gemt værdi

Derefter implementere processen med at indlæse de gemte data. Behandlingen af knappen er den samme som gemmeprocessen, så kun koden for indlæsningsprocessen er beskrevet her.

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

Brug metoden til at PlayerPrefs.GetString indlæse de gemte data. Du kan få værdien gemt med den pågældende nøgle ved at angive den nøgle, der er angivet i Gem som et argument. Værdien hentes i metodens returværdi.

Dette gemmes også som en streng på samme måde som ved lagring, så GetString vi kalder metoden. int float Hvis du gemmer med eller , skal du GetIntGetFloat kalde metoden.

Den hentede værdi afspejles i inputfeltet.

Du kan nu gemme og indlæse dataene. Jeg tror ikke, der er nogen vanskelige elementer.

Prøv at flytte den

Kør for at indtaste, gemme og indlæse. De gemte data bevares og bør kunne indlæses, selvom du afslutter og kører spillet igen. Hvis du kan bekræfte følgende mønster, tror jeg ikke, der er noget problem.

  1. Indtast en værdi
  2. Klik på knappen Gem
  3. Ændre den værdi, du har angivet
  4. Klik på importknappen for at bekræfte, at den vender tilbage til den gemte værdi.
  5. Afslut spillet
  6. Kør spillet igen, og klik på knappen Indlæs for at se, om du kan huske den gemte værdi
  7. Indtast en anden værdi, gem den, og kontroller, om du kan læse den samme med den opdaterede værdi

Gem og indlæs en del data

I stikprøven indtil videre er kun få parametre blevet gemt. Når du rent faktisk laver et spil, vil antallet af parametre, der skal gemmes, stige støt, og hvis du læser og skriver dem en efter en, vil koden være enorm. Derfor, når du opretter data, der faktisk skal gemmes, er teorien at kombinere de data, der skal gemmes, i en og derefter skrive det hele på én gang.

Opret først en lagringsdatastruktur som en klasse. Målet er at kunne læse og skrive data på én gang, men også at klassificere dataene for at gøre det lettere for kode at få adgang til hvert stykke data.

Følgende er eksempler på gemte spilklasser: Det kan skrives hvor som helst, det kan refereres fra anden kode. Denne klassestruktur er en prøve, så i et rigtigt spil skal du oprette det til dit spil.

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

I Unity-standardfunktionen List , der bruges denne gang, hvis du definerer arrays eller har flere unikke klasser, System.Serializable Hvis du ikke tilføjer en attribut, konverteres den ikke korrekt, så Character jeg indstiller attributten Serializable til klassen.

Når du har oprettet holdet, skal du oprette de data, der skal gemmes. Selvfølgelig kan du have forekomster af denne klasse i hele spillet. Dette afhænger af, hvordan spillet er lavet.

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

Når du har indstillet JsonUtility.ToJson dataene i klassens forekomst, skal du konvertere (serialisere) dem til en JSON-streng med metoden. Da objektets værdi er en enkelt "streng" kaldet JSON med en datastruktur, kan allePlayerPrefs.SetString data skrives med et enkelt opkald til metoden.

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

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

Men da alle data samles i en, er det ikke muligt kun at gemme en del af dem eller kun læse en del af dem. Derfor foretrækkes det at gøre det til en enhed, der er let at opsummere, såsom at kombinere det som et objekt til en gemme data.

Når du læser de gemte data, kan du foretage omvendt behandling, når du gemmer. De data, der skal læses, er en enkelt streng, men indholdet er JSON-formaterede datastrukturer, så JsonUtility.FromJson de kan konverteres (deserialiseres) til klasseforekomster ved hjælp af metoder. Men da vi ikke FromJson har oplysninger i strengen, hvilken klasse der skal konverteres til, skal vi specificere typen, når vi kalder metoden.

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

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

Hvis du forsøger at flytte det, kan du se, at det er gemt korrekt og kan indlæses.

Forresten bruger vi Unity-standardklasserne JsonUtility denne gang, men de er muligvis ikke i stand til at konvertere klasser med komplekse datastrukturer, fordi de ikke er særlig funktionelle. I så fald anbefales det at bruge andre biblioteker.

Hvor gemmes data?

PlayerPrefs Når du bruger et hold til at gemme data, afhænger placeringen, hvor de gemmes, af den platform, du kører på. Se venligst den officielle side nedenfor for, hvor den faktisk er gemt.

I nogle miljøer, såsom Windows, gemmes de ikke i en fil, men i systemindstillinger såsom registreringsdatabasen. Da det ikke er en fil, er det ikke egnet til at gemme gemte data i , for eksempel hvis de gemte data er meget store, eller PlayerPrefs du vil synkronisere de gemte data med et andet miljø. Omvendt, hvis de data, der skal gemmes, er størrelsen på indstillingsniveauet, eller hvis det er et selvstændigt spil, der kun afsluttes i det miljø, hvor det kører, tror jeg, det er PlayerPrefs muligt at gemme dataene i .

Derudover kan stien til den gemte placering blive påvirket af indstillingerne "Firmanavn" og "Produktnavn". Hvis du vil udgive dit spil, skal du beslutte dig for disse værdier i god tid og ikke ændre dem, når du udgiver dit spil.

Om datakryptering

Data, der gemmes, krypteres ikke automatisk. Hvis spillerens evner gemmes som de er, vil brugeren frit omskrive værdierne, hvilket vil påvirke spillet.

Har du brug for at kryptere, og hvis ja, hvilket niveau af styrke kræves, og hvordan håndterer du krypteringsnøglen? Ting at overveje varierer fra spil til spil.

Jeg vil ikke forklare krypteringsmetoden her, men hvis du slår det op på internettet, er det et vigtigt sprog og værktøj, så jeg tror, der er forskellige metoder. For øjeblikket, hvis du ikke forstår betydningen af det lagrede indhold, selvom du åbner filen, og hvis du manipulerer med dataene dårligt, vil du ikke være i stand til at bruge de gemte data, tror jeg, at der vil være en vis anti-svindeleffekt.