डेटा पढ़ने और लिखने के लिए PlayerPrefs का उपयोग करें
सत्यापन वातावरण
- विंडोज़
-
- विंडोज 11
- एकता संपादक
-
- 2021.3.3f1
- इनपुट सिस्टम पैकेज
-
- 1.3.0
इस टिप के लिए आवश्यक शर्तें
इस टिप के विवरण के लिए एक आधार के रूप में निम्नलिखित सेटिंग्स पहले से बनाई गई हैं।
पहले
यदि आपने गेम खेले हैं, तो आप में से अधिकांश ने इसका अनुभव किया है। आपने शायद एक गेम को रोक दिया है और छोड़ने के लिए अपना प्ले डेटा सहेजा या लोड किया है।
गेम बनाते समय, आपको आमतौर पर इस सेव और लोड फ़ंक्शन को बनाने, विकल्प सेट करने आदि की आवश्यकता होती है।
यहां, हम डेटा को स्टोर और लोड करने के सबसे PlayerPrefs
सरल तरीके का उपयोग करके इसे प्राप्त करने का प्रयास करेंगे।
UI Placement
यहां, हम इनपुट आइटम और बटन रखकर और बटन पर क्लिक करके इनपुट सामग्री को सहेजने या पढ़ने का प्रयास करेंगे। कुछ समय के लिए, आपको केवल कम से कम दो बटन और एक इनपुट फ़ील्ड की आवश्यकता है, इसलिए उन्हें रखने के लिए स्वतंत्र महसूस करें।
यूआई प्रोसेसिंग की तैयारी
सबसे पहले, चलो सहेजें बटन को लागू करते हैं। बटन ईवेंट कैसे बनाया जाए, यह निम्नलिखित युक्तियों में पेश किया गया है, इसलिए मैं केवल प्रासंगिक भागों को सूचीबद्ध करूंगा।
स्क्रिप्ट का नाम 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
यदि आप GetInt
GetFloat
इसके साथ बचत कर रहे हैं या , तो विधि को कॉल करें.
पुनर्प्राप्त मान इनपुट फ़ील्ड में परिलक्षित होता है।
अब आप डेटा सहेज और लोड कर सकते हैं। मुझे नहीं लगता कि कोई मुश्किल तत्व हैं।
इसे स्थानांतरित करने का प्रयास करें
प्रवेश करने, सहेजने और लोड करने के लिए चलाएँ. सहेजा गया डेटा बना रहता है और गेम से बाहर निकलने और फिर से चलाने पर भी लोड होने में सक्षम होना चाहिए। यदि आप निम्नलिखित पैटर्न की पुष्टि कर सकते हैं, तो मुझे लगता है कि कोई समस्या नहीं है।
- कोई मान दर्ज करें
- सहेजें बटन क्लिक करें
- आपके द्वारा दर्ज किया गया मान परिवर्तित करें
- यह पुष्टि करने के लिए आयात बटन क्लिक करें कि यह सहेजे गए मान पर लौटता है.
- खेल से बाहर निकलें
- गेम को फिर से चलाएं और यह देखने के लिए लोड बटन पर क्लिक करें कि क्या आप सहेजे गए मान को याद कर सकते हैं।
- एक अलग मान दर्ज करें, इसे सहेजें, और जांचें कि क्या आप अद्यतन मान के साथ इसे पढ़ सकते हैं
डेटा का एक हिस्सा सहेजें और लोड करें
अब तक के नमूने में, केवल कुछ पैरामीटर सहेजे गए हैं। जैसा कि आप वास्तव में एक गेम बनाते हैं, सहेजे जाने वाले मापदंडों की संख्या लगातार बढ़ेगी, और यदि आप उन्हें एक-एक करके पढ़ते और लिखते हैं, तो कोड बहुत बड़ा होगा। इसलिए, वास्तव में सहेजे जाने वाले डेटा बनाते समय, सिद्धांत यह है कि डेटा को एक में सहेजा जाए और फिर इसे एक बार में लिखा जाए।
सबसे पहले, एक वर्ग के रूप में एक सहेजें डेटा संरचना बनाएं। लक्ष्य एक बार में डेटा पढ़ने और लिखने में सक्षम होना है, लेकिन कोड के लिए डेटा के प्रत्येक टुकड़े तक पहुंचना आसान बनाने के लिए डेटा को वर्गीकृत करना भी है।
गेम क्लास सेव के उदाहरण निम्नलिखित हैं: इसे कहीं भी लिखा जा सकता है इसे अन्य कोड से संदर्भित किया जा सकता है। यह वर्ग संरचना एक नमूना है, इसलिए एक वास्तविक गेम में आपको इसे अपने गेम के लिए बनाने की आवश्यकता है।
<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
एकता मानक फ़ंक्शन में, यदि आप सरणी परिभाषित करते हैं या कई अद्वितीय कक्षाएं हैं,
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 नामक एक एकल "स्ट्रिंग" है, इसलिए सभी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
कक्षाओं का उपयोग कर रहे हैं, लेकिन वे जटिल डेटा संरचनाओं के साथ कक्षाओं को परिवर्तित करने में सक्षम नहीं हो सकते हैं क्योंकि वे बहुत कार्यात्मक नहीं हैं।
उस स्थिति में, अन्य पुस्तकालयों का उपयोग करने की सिफारिश की जाती है।
डेटा कहाँ संग्रहीत किया जाता है?
PlayerPrefs
जब आप डेटा संग्रहीत करने के लिए किसी वर्ग का उपयोग करते हैं, तो वह स्थान जहाँ वह सहेजा जाता है उस प्लेटफ़ॉर्म पर निर्भर करता है जिस पर आप चल रहे हैं.
कृपया नीचे दिए गए आधिकारिक पृष्ठ को देखें जहां यह वास्तव में संग्रहीत है।
कुछ वातावरणों में, जैसे कि विंडोज, वे फ़ाइल में संग्रहीत नहीं होते हैं, लेकिन रजिस्ट्री जैसी सिस्टम सेटिंग्स में।
चूंकि यह एक फ़ाइल नहीं है, इसलिए यह सहेजे गए डेटा को सहेजने के लिए उपयुक्त नहीं है, उदाहरण के लिए, यदि सहेजा गया डेटा बहुत बड़ा है या PlayerPrefs
आप सहेजे गए डेटा को किसी अन्य वातावरण के साथ सिंक्रनाइज़ करना चाहते हैं।
इसके विपरीत, यदि सहेजा जाने वाला डेटा विकल्प स्तर का आकार है, या यदि यह एक स्टैंडअलोन गेम है जो केवल उस वातावरण में पूरा होता है जिसमें यह चल रहा है, तो मुझे लगता है कि डेटा को सहेजना संभव है PlayerPrefs
।
इसके अतिरिक्त, सहेजे गए स्थान का पथ "कंपनी नाम" और "उत्पाद नाम" सेटिंग्स से प्रभावित हो सकता है। यदि आप अपना गेम प्रकाशित करना चाहते हैं, तो आपको इन मूल्यों पर पहले से निर्णय लेने की आवश्यकता है और अपना गेम प्रकाशित करने के बाद उन्हें नहीं बदलना होगा।
डेटा एन्क्रिप्शन के बारे में
संग्रहीत डेटा स्वचालित रूप से एन्क्रिप्ट डे नहीं है। यदि खिलाड़ी की क्षमताओं को सहेजा जाता है, तो उपयोगकर्ता स्वतंत्र रूप से मूल्यों को फिर से लिखेगा, जो खेल को प्रभावित करेगा।
क्या आपको एन्क्रिप्ट करने की आवश्यकता है, और यदि हां, तो किस स्तर की ताकत की आवश्यकता है, और आप एन्क्रिप्शन कुंजी को कैसे संभालते हैं? विचार करने के लिए चीजें अलग-अलग खेल में भिन्न होती हैं।
मैं यहां एन्क्रिप्शन विधि की व्याख्या नहीं करूंगा, लेकिन यदि आप इसे इंटरनेट पर देखते हैं, तो यह एक प्रमुख भाषा और उपकरण है, इसलिए मुझे लगता है कि विभिन्न तरीके हैं। फिलहाल, यदि आप फ़ाइल खोलने पर भी संग्रहीत सामग्री का अर्थ नहीं समझते हैं, और यदि आप डेटा के साथ खराब छेड़छाड़ करते हैं, तो आप सहेजे गए डेटा का उपयोग नहीं कर पाएंगे, मुझे लगता है कि कुछ एंटी-फ्रॉड प्रभाव होगा।