Använd PlayerPrefs för att läsa och skriva data

Sidan uppdaterad :
Datum för skapande av sida :

Verifiering miljö

Windows
  • Fönster 11
Unity-redaktör
  • 2021.3.3F1
Paket för inmatningssystem
  • 1.3.0

Förutsättningar för det här tipset

Följande inställningar har gjorts i förväg som en förutsättning för beskrivningen av detta tips.

Först

Om du har spelat spel har de flesta av er upplevt det. Du har förmodligen pausat ett spel och sparat eller laddat dina speldata för att lämna det.

När du skapar ett spel behöver du vanligtvis skapa den här spar- och laddningsfunktionen, ställa in alternativ etc. Här kommer vi att försöka uppnå detta med det enklaste PlayerPrefs sättet att lagra och ladda data.

Placering av användargränssnitt

Här försöker vi spara eller läsa inmatningsinnehållet genom att placera inmatningsobjekten och knapparna och klicka på knappen. För närvarande behöver du bara minst två knappar och ett inmatningsfält, så placera dem gärna.

Förbereda för UI-bearbetning

Låt oss först implementera spara-knappen. Hur man skapar en knapphändelse introduceras i följande tips, så jag listar bara relevanta delar.

Lämna skriptnamnet ButtonEvent som .

Skriptet ser ut så här:

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

Eftersom det är nödvändigt att få eller ställa in det angivna värdet, förbered det som ett fält. Inkludera också metoden som kommer att anropas när du klickar på varje knapp.

Koppla skriptet EventSystem till och ställ in varje inmatningsfält. Det kan vara vilket objekt du vill bifoga.

Ställ in varje metod som ska anropas när du klickar på knappen.

Spara värdet

Nu när metoden anropas när OnClickSave du klickar på spara-knappen är processen med spara-knappen som följer.

/// <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 är inställd på en nyckel och ett värde som ska sparas. Nyckeln anges när sparade data läses in. SetString Här kallar vi metoden eftersom värdet som ska lagras är en sträng. int float Om du vill SetInt spara ett värde av en annan typ, till exempel och , finns det metoder som och SetFloat , så anropa dem enligt typen.

PlayerPrefs.Save Slutligen, ring metoden för att bekräfta spara. Egentligen kan det sparas även om du inte kallar den här metoden, men det är säkrare att ringa den.

Men även om du kör spelet vid denna tidpunkt sparar det bara värdet, så du vet inte om det sparades ordentligt. Om du kontrollerar den sparade platsen kan du se data, men ...

Få ett sparat värde

Implementera sedan processen för att ladda sparade data. Bearbetningen av knappen är densamma som sparprocessen, så endast koden för laddningsprocessen beskrivs här.

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

Använd metoden för att PlayerPrefs.GetString läsa in sparade data. Du kan spara värdet med den nyckeln genom att ange nyckeln som anges i Spara som ett argument. Värdet hämtas i metodens returvärde.

Detta sparas också som en sträng på samma sätt som när du sparar, så GetString vi kallar metoden. int float Om du sparar med eller anropar du GetIntGetFloat metoden.

Det hämtade värdet återspeglas i inmatningsfältet.

Du kan nu spara och ladda data. Jag tror inte att det finns några svåra element.

Prova att flytta den

Kör för att ange, spara och ladda. Den sparade informationen bevaras och bör kunna laddas även om du avslutar och kör spelet igen. Om du kan bekräfta följande mönster tror jag att det inte finns några problem.

  1. Ange ett värde
  2. Klicka på knappen Spara
  3. Ändra värdet du angav
  4. Klicka på importknappen för att bekräfta att den återgår till det sparade värdet.
  5. Avsluta spelet
  6. Kör spelet igen och klicka på laddningsknappen för att se om du kan komma ihåg det sparade värdet
  7. Ange ett annat värde, spara det och kontrollera om du kan läsa samma med det uppdaterade värdet

Spara och ladda en bit data

I exemplet hittills har endast ett fåtal parametrar sparats. När du faktiskt gör ett spel kommer antalet parametrar som ska sparas att öka stadigt, och om du läser och skriver dem en efter en blir koden enorm. Därför, när du skapar data som faktiskt ska sparas, är teorin att kombinera data som ska sparas i en och sedan skriva allt på en gång.

Skapa först en spara datastruktur som en klass. Målet är att kunna läsa och skriva data på en gång, men också att klassificera data för att göra det lättare för kod att komma åt varje data.

Följande är exempel på spara spelklasser: Det kan skrivas var som helst det kan refereras från annan kod. Denna klassstruktur är ett prov, så i ett riktigt spel måste du skapa det för ditt spel.

/// <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 som används den List här gången, om du definierar matriser eller har flera unika klasser, System.Serializable Om du inte lägger till ett attribut konverteras det inte korrekt, så Character jag ställer in attributet till Serializable klassen.

När du har skapat klassen skapar du de data som ska sparas. Naturligtvis kan du ha instanser av denna klass under hela spelet. Detta beror på hur spelet görs.

// 保存するデータ作成
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 angett JsonUtility.ToJson data i instansen av klassen konverterar (serialiserar) du dem till en JSON-sträng med metoden. Eftersom objektets värde är en enda "sträng" som heter JSON med en datastruktur kan allaPlayerPrefs.SetString data skrivas med ett enda anrop till metoden.

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

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

Men eftersom all data samlas in i en, är det inte möjligt att spara bara en del av det eller bara läsa en del av det. Därför är det bättre att göra det till en enhet som är lätt att sammanfatta, till exempel att kombinera den som ett objekt för en spara data.

När du läser sparade data kan du göra omvänd bearbetning när du sparar. Data som ska läsas är en enda sträng, men innehållet är JSON-formaterade datastrukturer, så JsonUtility.FromJson de kan konverteras (deserialiseras) till klassinstanser med metoder. Men eftersom vi inte FromJson har information i strängen vilken klass vi ska konvertera till, måste vi ange typen när vi anropar metoden.

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

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

Om du försöker flytta den kan du se att den sparas korrekt och kan laddas.

Förresten, vi använder Unity-standardklasserna JsonUtility den här gången, men de kanske inte kan konvertera klasser med komplexa datastrukturer eftersom de inte är särskilt funktionella. I så fall rekommenderas att du använder andra bibliotek.

Var lagras data?

PlayerPrefs När du använder en klass för att lagra data beror platsen där den sparas på vilken plattform du kör på. Se den officiella sidan nedan för var den faktiskt lagras.

I vissa miljöer, till exempel Windows, lagras de inte i en fil utan i systeminställningar som registret. Eftersom det inte är en fil är den inte lämplig för att spara sparade data i , till exempel om spara data är mycket stora eller PlayerPrefs om du vill synkronisera spara data med en annan miljö. Omvänt, om data som ska sparas är storleken på alternativnivån, eller om det är ett fristående spel som endast slutförs i den miljö där det körs, tror jag att det är PlayerPrefs möjligt att spara data i .

Dessutom kan sökvägen till den sparade platsen påverkas av inställningarna "Företagsnamn" och "Produktnamn". Om du vill publicera ditt spel måste du bestämma dessa värden i god tid och inte ändra dem när du publicerar ditt spel.

Om datakryptering

Data som lagras krypteras inte automatiskt. Om spelarens förmågor sparas som de är, kommer användaren fritt att skriva om värdena, vilket kommer att påverka spelet.

Behöver du kryptera, och i så fall vilken styrka krävs, och hur hanterar du krypteringsnyckeln? Saker att tänka på varierar från spel till spel.

Jag kommer inte att förklara krypteringsmetoden här, men om du slår upp det på Internet är det ett stort språk och verktyg, så jag tror att det finns olika metoder. För tillfället, om du inte förstår innebörden av det lagrade innehållet även om du öppnar filen, och om du manipulerar uppgifterna dåligt, kommer du inte att kunna använda spara data, jag tror att det kommer att bli någon bedrägeribekämpningseffekt.