在Unity中首先創建一個Save腳本,用於保存遊戲中相關的信息,在這裏我存儲的是遊戲中怪物的位置以及類型、遊戲射擊總數量、遊戲得分等數據,Save腳本的代碼如下(這個腳本是不能掛在在場景中的遊戲物體上,因爲這個類沒有繼承自MonoBehaviour行爲類):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//串行化,串行化是指存儲和獲取磁盤文件、內存或其他地方中的對象。
[System.Serializable]
public class Save {
public List<int> livingTargetPosition = new List<int>();
public List<int> livingMonsterTypes = new List<int>();
public int shootNum = 0;
public int score = 0;
}
然後再創建一個腳本GameManager,並放置以下的方法:
//創建Save對象並存儲當前遊戲狀態信息
private Save CreateSaveGO()
{
//新建Save對象
Save save = new Save();
//遍歷所有的Target
//如果其中有激活狀態的怪物,就把該target的位置信息和激活狀態的怪物的類型添加到List中
//targetGOs是存儲遊戲中所有怪物的一個一維數組
foreach (GameObject targetGO in targetGOs)
{
TargetManager targetManager = targetGO.GetComponent<TargetManager>();
//當這個數組中某一個元素中有怪物的時候
if(targetManager.target != null)
{
save.livingTargetPosition.Add(targetManager.targetPosition);
int type = targetManager.target.GetComponent<MonsterManager>().monsterType;
save.livingMonsterTypes.Add(type);
}
}
//把shootNum和socre保存到Save對象中
save.shootNum = UIManager._instance.shootNum;
save.score = UIManager._instance.scoreNum;
//返回Save對象
return save;
}
下面就是重點來了,開始XML的存檔和讀檔部分!
XML的存檔方法:
private void SaveByXml()
{
//獲得保存遊戲信息的save
Save save = CreateSaveGO();
//創建XML文件的存儲路徑
string filePath = Application.dataPath + "/StreamFile" + "/byXML.txt";
//創建XML文檔(注意這裏要引入命名空間using System.Xml)
XmlDocument xmlDoc = new XmlDocument();
//創建根節點,即最上層節點
XmlElement root = xmlDoc.CreateElement("save");
//設置根節點中的值
root.SetAttribute("name", "saveFile1");
//創建XmlElement
XmlElement target;
XmlElement targetPosition;
XmlElement monsterType;
//遍歷save中存儲的數據,將數據轉換成XML格式
for (int i = 0; i < save.livingTargetPosition.Count; i++)
{
target = xmlDoc.CreateElement("target");
targetPosition = xmlDoc.CreateElement("targetPosition");
//設置InnerText值
targetPosition.InnerText = save.livingTargetPosition[i].ToString();
monsterType = xmlDoc.CreateElement("monsterType");
monsterType.InnerText = save.livingMonsterTypes[i].ToString();
//設置節點間的層級關係 root -- target --(targetPosition,monsterType)
target.AppendChild(targetPosition);
target.AppendChild(monsterType);
root.AppendChild(target);
}
//設置射擊數和分數節點並設置層級關係 xmlDoc -- root --(target -- (targetPosition,monsterType),shootNum,score)
XmlElement shootNum = xmlDoc.CreateElement("shootNum");
shootNum.InnerText = save.shootNum.ToString();
root.AppendChild(shootNum);
XmlElement score = xmlDoc.CreateElement("score");
score.InnerText = save.score.ToString();
root.AppendChild(score);
xmlDoc.AppendChild(root);
xmlDoc.Save(filePath);
if(File.Exists(Application.dataPath + "/StreamFile" + "/byXML.txt"))
{
UIManager._instance.ShowMessages("保存成功");
}
}
XML的讀檔方法:
private void LoadByXml()
{
//讀取XML文件的存儲路徑
string filePath = Application.dataPath + "/StreamFile" + "/byXML.txt";
//如果這個文件不存在的話
if (File.Exists(filePath))
{
Save save = new Save();
//加載XML文檔
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filePath);
//通過節點名稱來獲取元素,結果爲XmlNodeList類型
XmlNodeList targets = xmlDoc.GetElementsByTagName("target");
//遍歷所有的target節點,並獲得子節點和子節點的InnerText
if(targets.Count != 0)
{
foreach (XmlNode target in targets)
{
XmlNode targetPosition = target.ChildNodes[0];
int targetPositionIndex = int.Parse(targetPosition.InnerText);
//把得到的值存儲在save中
save.livingTargetPosition.Add(targetPositionIndex);
XmlNode monsterType = target.ChildNodes[1];
int monsterTypeIndex = int.Parse(monsterType.InnerText);
save.livingMonsterTypes.Add(monsterTypeIndex);
}
}
//得到存儲的射擊數和分數
XmlNodeList shootNum = xmlDoc.GetElementsByTagName("shootNum");
int shootNumCount = int.Parse(shootNum[0].InnerText);
save.shootNum = shootNumCount;
XmlNodeList score = xmlDoc.GetElementsByTagName("score");
int scoreCount = int.Parse(score[0].InnerText);
save.score = scoreCount;
//調用激活怪物以及更新分數的UI方法
SetGame(save);
UIManager._instance.ShowMessages("");
}
else
{
UIManager._instance.ShowMessages("存檔文件不存在");
}
}
根據讀出的信息,進行激活怪物,以及更新場景分數UI的SetGame方法:
private void SetGame(Save save)
{
//先將所有的target裏面的怪物清空,並重置所有的計時
foreach (GameObject targetGo in targetGOs)
{
targetGo.GetComponent<TargetManager>().UpdateMonsters();
}
//通過反系列化得到的Save對象中存儲的信息,激活指定的怪物
for (int i = 0; i < save.livingTargetPosition.Count; i++)
{
int position = save.livingTargetPosition[i];
int type = save.livingMonsterTypes[i];
targetGOs[position].GetComponent<TargetManager>().ActivateMonsterByType(type);
}
//更新UI提示
UIManager._instance.shootNum = save.shootNum;
UIManager._instance.scoreNum = save.score;
//調整爲未暫停狀態
UnPause();
}
好了,如果還有不懂得地方可以去這個網址觀看完整版的數據存檔和讀檔!(http://www.sikiedu.com/my/course/129),如果您覺得這篇文章寫的還可以的話,不妨動動您的小手指,給俺點個贊,謝謝大家!