ใช้ PlayerPrefs เพื่ออ่านและเขียนข้อมูล

ปรับปรุงหน้า :
วันที่สร้างเพจ :

สภาพแวดล้อมการตรวจสอบ

หน้าต่าง
  • หน้าต่าง 11
บรรณาธิการ Unity
  • ปี 2021.3.3f1
แพ็คเกจระบบอินพุต
  • 1.3.0

ข้อกําหนดเบื้องต้นสําหรับเคล็ดลับนี้

การตั้งค่าต่อไปนี้ได้ทําไว้ล่วงหน้าเพื่อเป็นหลักฐานสําหรับคําอธิบายของเคล็ดลับนี้

ทีแรก

หากคุณเคยเล่นเกมพวกคุณส่วนใหญ่เคยมีประสบการณ์ คุณอาจหยุดเกมชั่วคราวและบันทึกหรือโหลดข้อมูลการเล่นของคุณเพื่อปิด

เมื่อสร้างเกมคุณมักจะต้องสร้างฟังก์ชั่นบันทึกและโหลดตั้งค่าตัวเลือก ฯลฯ ที่นี่เราจะพยายามบรรลุเป้าหมายนี้โดยใช้วิธีที่ง่ายที่สุด PlayerPrefs ในการจัดเก็บและโหลดข้อมูล

ตําแหน่ง UI

ที่นี่เราจะพยายามบันทึกหรืออ่านเนื้อหาอินพุตโดยวางรายการและปุ่มอินพุตแล้วคลิกปุ่ม ในขณะนี้คุณต้องมีปุ่มอย่างน้อยสองปุ่มและช่องป้อนข้อมูลหนึ่งช่องดังนั้นอย่าลังเลที่จะวางไว้

การเตรียมพร้อมสําหรับการประมวลผล 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เรียกวิธีการนี้ 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 ข้อมูลในอินสแตนซ์ของคลาสแล้วให้แปลง (serialize) เป็นสตริง JSON ด้วยวิธีการ เนื่องจากค่าของวัตถุเป็น "สตริง" เดียวที่เรียกว่า JSON ที่มีโครงสร้างข้อมูลข้อมูลทั้งหมดPlayerPrefs.SetString จึงสามารถเขียนได้ด้วยการเรียกเพียงครั้งเดียวไปยังวิธีการ

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

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

อย่างไรก็ตามเนื่องจากข้อมูลทั้งหมดถูกรวบรวมไว้ในที่เดียวจึงไม่สามารถบันทึกได้เพียงบางส่วนหรืออ่านเพียงบางส่วนเท่านั้น ดังนั้นจึงเป็นการดีกว่าที่จะทําให้เป็นหน่วยที่สรุปได้ง่ายเช่นการรวมเป็นวัตถุเดียวสําหรับการบันทึกข้อมูลหนึ่งครั้ง

เมื่ออ่านข้อมูลที่บันทึกไว้คุณสามารถทําการประมวลผลย้อนกลับเมื่อบันทึก ข้อมูลที่จะอ่านเป็นสตริงเดียว แต่เนื้อหาเป็นโครงสร้างข้อมูลที่จัดรูปแบบ JSON ดังนั้นจึง JsonUtility.FromJson สามารถแปลง (deserialized) เป็นอินสแตนซ์คลาสโดยวิธีการ อย่างไรก็ตามเนื่องจากเราไม่ FromJson มีข้อมูลในสตริงว่าจะแปลงเป็นคลาสใดเราจึงต้องระบุประเภทเมื่อเรียกวิธีการ

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

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

หากคุณพยายามย้ายคุณจะเห็นว่ามันถูกบันทึกไว้อย่างถูกต้องและสามารถโหลดได้

อย่างไรก็ตามเรากําลังใช้คลาสมาตรฐาน JsonUtility Unity ในครั้งนี้ แต่พวกเขาอาจไม่สามารถแปลงคลาสที่มีโครงสร้างข้อมูลที่ซับซ้อนได้เนื่องจากทํางานได้ไม่มากนัก ในกรณีนี้ขอแนะนําให้ใช้ไลบรารีอื่น ๆ

ข้อมูลถูกจัดเก็บไว้ที่ใด

PlayerPrefs เมื่อคุณใช้คลาสเพื่อจัดเก็บข้อมูลตําแหน่งที่บันทึกจะขึ้นอยู่กับแพลตฟอร์มที่คุณใช้งาน โปรดดูหน้าอย่างเป็นทางการด้านล่างสําหรับตําแหน่งที่จัดเก็บจริง

ในบางสภาพแวดล้อมเช่น Windows พวกเขาจะไม่ถูกเก็บไว้ในไฟล์ แต่ในการตั้งค่าระบบเช่นรีจิสทรี เนื่องจากไม่ใช่ไฟล์จึงไม่เหมาะสําหรับการบันทึกข้อมูลที่บันทึกไว้ใน ตัวอย่างเช่นหากข้อมูลบันทึกมีขนาดใหญ่มากหรือ PlayerPrefs คุณต้องการซิงโครไนซ์ข้อมูลที่บันทึกกับสภาพแวดล้อมอื่น ในทางกลับกันหากข้อมูลที่จะบันทึกคือขนาดของระดับตัวเลือกหรือหากเป็นเกมแบบสแตนด์อโลนที่เสร็จสมบูรณ์เฉพาะในสภาพแวดล้อมที่กําลังทํางานอยู่ฉันคิดว่ามัน PlayerPrefs เป็นไปได้ที่จะบันทึกข้อมูลใน .

นอกจากนี้ เส้นทางของตําแหน่งที่ตั้งที่บันทึกไว้อาจได้รับผลกระทบจากการตั้งค่า "ชื่อบริษัท" และ "ชื่อผลิตภัณฑ์" หากคุณต้องการเผยแพร่เกมของคุณคุณต้องตัดสินใจเลือกค่าเหล่านี้ล่วงหน้าและไม่เปลี่ยนแปลงเมื่อคุณเผยแพร่เกมของคุณ

เกี่ยวกับการเข้ารหัสข้อมูล

ข้อมูลที่จัดเก็บจะไม่ถูกเข้ารหัสโดยอัตโนมัติ หากความสามารถของผู้เล่นได้รับการบันทึกตามที่เป็นอยู่ผู้ใช้จะเขียนค่าใหม่ได้อย่างอิสระซึ่งจะส่งผลต่อเกม

คุณต้องเข้ารหัสหรือไม่และถ้าเป็นเช่นนั้นต้องใช้ความแข็งแกร่งในระดับใดและคุณจัดการกับคีย์การเข้ารหัสอย่างไร สิ่งที่ต้องพิจารณาแตกต่างกันไปในแต่ละเกม

ฉันจะไม่อธิบายวิธีการเข้ารหัสที่นี่ แต่ถ้าคุณค้นหาบนอินเทอร์เน็ตมันเป็นภาษาและเครื่องมือที่สําคัญดังนั้นฉันคิดว่ามีวิธีการต่างๆ ในขณะนี้หากคุณไม่เข้าใจความหมายของเนื้อหาที่เก็บไว้แม้ว่าคุณจะเปิดไฟล์และหากคุณยุ่งเกี่ยวกับข้อมูลไม่ดีคุณจะไม่สามารถใช้ข้อมูลที่บันทึกไว้ได้ฉันคิดว่าจะมีผลต่อต้านการฉ้อโกง