我几乎完成了手机游戏的制作,并且我有一个使用this视频中显示的内容的DATA脚本。我有一个列表,其中包含玩家可以完成的各种挑战的值。我将如何更新游戏,以便在保留旧数据的同时增加更多挑战。
(挑战数据基本上包含它是否已经完成以及完成的距离有多远)
我看过this指南,但我不太理解。我是序列化的新手。
预先感谢您:)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
[System.Serializable]
public class XMLManager : MonoBehaviour {
public static XMLManager dataManagement;
public gameData data;
void Awake()
{
//File.Delete(Application.dataPath + "/StreamingFiles/XML/item_data.xml");
System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
dataManagement = this;
DontDestroyOnLoad(gameObject);
}
public void SaveData()
{
XmlSerializer serializer = new XmlSerializer(typeof(gameData));
System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
FileStream stream = new FileStream(Application.dataPath + "/StreamingFiles/XML/item_data.xml", FileMode.Create);
serializer.Serialize(stream, data);
stream.Close();
}
public void LoadData()
{
System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
if (File.Exists(Application.dataPath + "/StreamingFiles/XML/item_data.xml"))
{
XmlSerializer serializer = new XmlSerializer(typeof(gameData));
FileStream stream = new FileStream(Application.dataPath + "/StreamingFiles/XML/item_data.xml", FileMode.Open);
data = serializer.Deserialize(stream) as gameData;
stream.Close();
}
else
{
print("SaveData");
SaveData();
}
}
}
[System.Serializable]
public class gameData
{
public List<ChallengeStatus> Challenges;
public int HighScore;
public int CoinsCollected;
public List<bool> Unlocked;
public int GamesPlayed;
public int currentChallenge;
}
[System.Serializable]
public class ChallengeStatus
{
public int id;
public string title;
public int current;
public int max;
public int reward;
public bool completed;
public bool claimed;
}
答案 0 :(得分:0)
首先,您应该查看Unity XML Serialization并使用适当的属性。您并非完全不需要它们(也许[XmlRoot]
除外),但是它们使您可以自定义Xml文件。如果未提供,Unity将使用变量名称,并使用子元素而不是属性。但是,afaik仅适用于原语(int
,float
,string
,bool
等),并且不适用于您自己的类ChallengeStatus
。因此,至少对于您的课程列表,您必须提供属性:
[System.Serializable]
[XmlRoot("GameData")]
public class GameData
{
[XmlArray("Challenges")]
[XmlArrayItem("ChallengeStatus)]
public List<ChallengeStatus> Challenges;
//...
}
现在我不太明白为什么保存新的XML文件时需要保留旧的XML文件,但是如果要保留当前的文件,我会添加int FileCounter
..当然不是使用相同的XML文件;)可能是例如通过PlayerPrefs或另一个仅包含数字或类似内容的简单文本文件。
请注意,最好使用Path.Combine来连接系统路径)-重载采用字符串数组需要.Net4。像
private string FilePath
{
get
{
//TODO first load / read the FileCounter from somewhere
var paths = {
Application.dataPath,
"StreamingFiles",
"XML",
// here you get from somewhere and use that global FileCounter
string.Format("item_data_{0}.xml", FileCounter)};
return Path.Combine(paths);
}
}
每次您保存文件时,都可以增加全局FileCounter
。
public void SaveData()
{
//TODO somehow increase the global value
// store to PlayerPrefs or write a new file or ...
FileCounter += 1;
System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
// better use the "using" keyword for streams
// use the FilePath field to get the filepath including the filecounter
using(FileStream stream = new FileStream(FilePath, FileMode.Create))
{
XmlSerializer serializer = new XmlSerializer(typeof(gameData))
serializer.Serialize(stream, data);
}
}
并使用当前的FileCounter
读取文件而无需增加文件
public void LoadData()
{
System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
if (File.Exists(FilePath))
{
// better use a "using" block for streams
// use the FilePath field to get the filepath including the filecounter
using(FileStream stream = new FileStream(FilePath, FileMode.Open))
{
XmlSerializer serializer = new XmlSerializer(typeof(gameData));
data = serializer.Deserialize(stream) as gameData;
}
}
else
{
print("SaveData");
SaveData();
}
}
提示1 :
一旦为您的类提供了构造函数,例如
public GameData(List<ChallengeStatus> challenges)
{
Challenges = challenges;
}
比您总是还要提供一个默认的构造函数(即使它什么也不做)
public GameData(){ }
提示2:
您应该始终初始化列表:
public class GameData
{
public List<ChallengeStatus> Challenges = new List≤ChallangeStatus>();
//...
public List<bool> Unlocked = new List<bool>();
//...
}
提示3 :
顺便说一句,您不需要[System.Serializable]
的{{1}},因为它是从XmlManager
继承的,而该MonoBehaviour
已经可以序列化了。