2016-12-05 8 views
6

मुझे यूनिटी 3 डी गेम इंजन में गेम डेटा सहेजने का सबसे अच्छा तरीका मिल गया है।
सबसे पहले, मैं BinaryFormatter का उपयोग करके वस्तुओं को क्रमबद्ध करता हूं।गेम स्थिति को सहेजने का सबसे अच्छा तरीका क्या है?

लेकिन मैंने सुना है कि इस तरह के कुछ मुद्दे हैं और यह सहेजने के लिए उपयुक्त नहीं है।
तो, खेल राज्य को बचाने के लिए सबसे अच्छा या अनुशंसित तरीका क्या है?

मेरे मामले में, सहेजें प्रारूप बाइट सरणी होना चाहिए।

+0

क्यों अपने प्रारूप एक बाइट सरणी होना चाहिए? इसे PlayerPrefs में क्यों न सहेजें? –

+1

क्रमबद्धरण का उपयोग करने में समस्या क्या है? –

उत्तर

20

लेकिन मैंने सुना है कि इस तरह के कुछ मुद्दे हैं और सहेजने के लिए उपयुक्त नहीं हैं।

यह सही है। कुछ उपकरणों पर, BinaryFormatter के साथ समस्याएं हैं। जब आप कक्षा को अपडेट या बदलते हैं तो यह बदतर हो जाता है। कक्षाएं अब मेल नहीं होने के बाद आपकी पुरानी सेटिंग्स खो सकती हैं। कभी-कभी, इसके कारण सहेजे गए डेटा को पढ़ने पर आपको अपवाद मिलता है।

इसके अलावा, आईओएस पर, आपको Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes"); जोड़ना होगा या आपको BinaryFormatter में समस्या होगी।

सहेजने का सबसे अच्छा तरीका PlayerPrefs और Json के साथ है। आप सीख सकते हैं कि here कैसे करें।

मेरे मामले में, को बचाने के प्रारूप बाइट सरणी होना चाहिए

इस मामले में, आप JSON करने के लिए तो json परिवर्तित stringbyte सरणी करने के लिए इसे बदल सकते हैं। बाइट सरणी को सहेजने और पढ़ने के लिए आप File.WriteAllBytes और File.ReadAllBytes का उपयोग कर सकते हैं।

यहां एक जेनेरिक क्लास है जिसका उपयोग डेटा को सहेजने के लिए किया जा सकता है। this के समान लगभग PlayerPrefs का उपयोग करें। यह जेसन डेटा को सहेजने के लिए फ़ाइल का उपयोग करता है।

DataSaver वर्ग:

public class DataSaver 
{ 
    //Save Data 
    public static void saveData<T>(T dataToSave, string dataFileName) 
    { 
     string tempPath = Path.Combine(Application.persistentDataPath, "data"); 
     tempPath = Path.Combine(tempPath, dataFileName + ".txt"); 

     //Convert To Json then to bytes 
     string jsonData = JsonUtility.ToJson(dataToSave, true); 
     byte[] jsonByte = Encoding.ASCII.GetBytes(jsonData); 

     //Create Directory if it does not exist 
     if (!Directory.Exists(Path.GetDirectoryName(tempPath))) 
     { 
      Directory.CreateDirectory(Path.GetDirectoryName(tempPath)); 
     } 
     //Debug.Log(path); 

     try 
     { 
      File.WriteAllBytes(tempPath, jsonByte); 
      Debug.Log("Saved Data to: " + tempPath.Replace("/", "\\")); 
     } 
     catch (Exception e) 
     { 
      Debug.LogWarning("Failed To PlayerInfo Data to: " + tempPath.Replace("/", "\\")); 
      Debug.LogWarning("Error: " + e.Message); 
     } 
    } 

    //Load Data 
    public static T loadData<T>(string dataFileName) 
    { 
     string tempPath = Path.Combine(Application.persistentDataPath, "data"); 
     tempPath = Path.Combine(tempPath, dataFileName + ".txt"); 

     //Exit if Directory or File does not exist 
     if (!Directory.Exists(Path.GetDirectoryName(tempPath))) 
     { 
      Debug.LogWarning("Directory does not exist"); 
      return default(T); 
     } 

     if (!File.Exists(tempPath)) 
     { 
      Debug.Log("File does not exist"); 
      return default(T); 
     } 

     //Load saved Json 
     byte[] jsonByte = null; 
     try 
     { 
      jsonByte = File.ReadAllBytes(tempPath); 
      Debug.Log("Loaded Data from: " + tempPath.Replace("/", "\\")); 
     } 
     catch (Exception e) 
     { 
      Debug.LogWarning("Failed To Load Data from: " + tempPath.Replace("/", "\\")); 
      Debug.LogWarning("Error: " + e.Message); 
     } 

     //Convert to json string 
     string jsonData = Encoding.ASCII.GetString(jsonByte); 

     //Convert to Object 
     object resultValue = JsonUtility.FromJson<T>(jsonData); 
     return (T)Convert.ChangeType(resultValue, typeof(T)); 
    } 

    public static bool deleteData(string dataFileName) 
    { 
     bool success = false; 

     //Load Data 
     string tempPath = Path.Combine(Application.persistentDataPath, "data"); 
     tempPath = Path.Combine(tempPath, dataFileName + ".txt"); 

     //Exit if Directory or File does not exist 
     if (!Directory.Exists(Path.GetDirectoryName(tempPath))) 
     { 
      Debug.LogWarning("Directory does not exist"); 
      return false; 
     } 

     if (!File.Exists(tempPath)) 
     { 
      Debug.Log("File does not exist"); 
      return false; 
     } 

     try 
     { 
      File.Delete(tempPath); 
      Debug.Log("Data deleted from: " + tempPath.Replace("/", "\\")); 
      success = true; 
     } 
     catch (Exception e) 
     { 
      Debug.LogWarning("Failed To Delete Data: " + e.Message); 
     } 

     return success; 
    } 
} 

उपयोग:

उदाहरण वर्ग सहेजें करने के लिए:

[Serializable] 
public class PlayerInfo 
{ 
    public List<int> ID = new List<int>(); 
    public List<int> Amounts = new List<int>(); 
    public int life = 0; 
    public float highScore = 0; 
} 

डेटा सहेजें:

PlayerInfo saveData = new PlayerInfo(); 
saveData.life = 99; 
saveData.highScore = 40; 

//Save data from PlayerInfo to a file named players 
DataSaver.saveData(saveData, "players"); 

लोड डाटा:

PlayerInfo loadedData = DataSaver.loadData<PlayerInfo>("players"); 
if (loadedData == null) 
{ 
    return; 
} 

//Display loaded Data 
Debug.Log("Life: " + loadedData.life); 
Debug.Log("High Score: " + loadedData.highScore); 

for (int i = 0; i < loadedData.ID.Count; i++) 
{ 
    Debug.Log("ID: " + loadedData.ID[i]); 
} 
for (int i = 0; i < loadedData.Amounts.Count; i++) 
{ 
    Debug.Log("Amounts: " + loadedData.Amounts[i]); 
} 

हटाएं डाटा:

DataSaver.deleteData("players"); 
+0

धन्यवाद! क्योंकि हमारे प्रोजेक्ट को मोनो 2 एक्स सेटिंग की आवश्यकता है, इसलिए हम उस पर्यावरण सेटिंग में विफल रहे। मैं जेसन उपयोगिता और आपकी टिप्पणी करने की कोशिश करूंगा! – Sizzling

संबंधित मुद्दे