1.设置Target位置和怪物类型
修改TargetManager中的一些代码
//保存所有该目标下的怪物和当前激活状态下的怪物
public GameObject[] monsters;
public GameObject activeMaonster = null;
//表示目标所在的位置(0-8)
public int targetPosition;
//通过Type来激活怪物
public void ActivateMonsterByType(int type)
{
StopAllCoroutines();
if (activeMaonster != null)
{
activeMaonster.GetComponent<BoxCollider>().enabled = false;
activeMaonster.SetActive(false);
activeMaonster = null;
}
activeMaonster = monsters[type];
activeMaonster.SetActive(true);
activeMaonster.GetComponent<BoxCollider>().enabled = true;
StartCoroutine("DeathTimer");
}
2.复制Target并完善
3.创建Save保存类
首先创建一个Save类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Save {
public List<int> livingTargetPositions = 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中
foreach(GameObject targetGo in targetGos)
{
TargetManager targetManager = targetGo.GetComponent<TargetManager>();
if (targetManager.activeMaonster != null)
{
save.livingTargetPositions.Add(targetManager.targetPosition);
int type = targetManager.activeMaonster.GetComponent<MonsterManager>().monsterType;
save.livingMonsterTypes.Add(type);
}
}
//把shootNum和score保存在Save对象中
save.shootNum = UIManager._instance.shootNum;
save.score = UIManager._instance.score;
//返回该Save对象
return save;
}
4.保存游戏(二进制方法)
//二进制:读档和存档
private void SaveByBin()
{
//序列化过程(将Save对象转换为字节流)
//创建Save对象并保存当前游戏状态
Save save = CreateSaveGo();
//创建一个二进制格式化程序
BinaryFormatter bf = new BinaryFormatter();
//创建一个文件流
FileStream fileStream = File.Create(Application.dataPath + "/StreamingFile" + "/byBin.txt");
//用二进制格式化程序的序列化方法来序列化Save对象,参数:创建的文件流和需要序列化的对象
bf.Serialize(fileStream, save);
//关闭流
fileStream.Close();
}
5.读取游戏(二进制方法)
在GameManager中添加读取游戏的方法
private void LoadByBin()
{
if(File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt"))
{
//反序列化过程
//创建一个二进制格式化程序
BinaryFormatter bf = new BinaryFormatter();
//打开一个文件流
FileStream fileStream = File.Open(Application.dataPath + "/StreamingFile" + "/byBin.txt", FileMode.Open);
//调用格式化程序的反序列化,将文件流转换为一个Save对象
Save save = (Save)bf.Deserialize(fileStream);
//关闭文件流
fileStream.Close();
SetGame(save);
}
else
{
UIManager._instance.ShowMessage("存档文件不存在!");
}
}
private void SetGame(Save save)
{
//先将所有的target里面的怪物清空,并重置所有的计时
foreach(GameObject targetGo in targetGos)
{
targetGo.GetComponent<TargetManager>().UpdateMonsters();
}
//通过反序列化得到Save对象中存储的信息,激活指定的怪物
for(int i = 0; i < save.livingTargetPositions.Count; i++)
{
int position = save.livingTargetPositions[i];
int type = save.livingMonsterTypes[i];
targetGos[position].GetComponent<TargetManager>().ActivateMonsterByType(type);
}
//更新UI显示
UIManager._instance.shootNum = save.shootNum;
UIManager._instance.score = save.score;
//调整为为暂停状态
UnPause();
}
//加载游戏
public void LoadGame()
{
LoadByBin();
UIManager._instance.ShowMessage("");
}
结果如下
6.保存游戏(JSON)
在GameManager中添加用Json保存游戏的方法
using LitJson;
private void SaveByJson()
{
Save save = CreateSaveGo();
string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
//利用JsonMapper将save对象转换为Json格式的字符串
string saveJsonStr = JsonMapper.ToJson(save);
//将这个字符串写入到文件中
//创建一个StreamWriter,并将字符串写入文件中
StreamWriter sw = new StreamWriter(filePath);
sw.Write(saveJsonStr);
//关闭StreamWriter
sw.Close();
UIManager._instance.ShowMessage("保存成功!");
}
结果如下
{"livingTargetPositions":[1,3,4,5,8],"livingMonsterTypes":[2,0,0,2,3],"shootNum":4,"score":2}
7.读取游戏(JSON)
private void LoadByJson()
{
string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
if(File.Exists(Application.dataPath + "/StreamingFile" + "/byJson.json"))
{
//创建一个StreamReader,用来读取流
StreamReader sr = new StreamReader(filePath);
//将读取到的流赋值给jsonStr
string jsonStr = sr.ReadToEnd();
sr.Close();
//将字符串jsonStr转换为Save对象
Save save = JsonMapper.ToObject<Save>(jsonStr);
SetGame(save);
UIManager._instance.ShowMessage("");
}
else
{
UIManager._instance.ShowMessage("存档文件不存在!");
}
}
8.保存游戏(XML)
//Xml:读档和存档
private void SaveByXml()
{
Save save = CreateSaveGo();
//创建XML文件的存储路径
string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";
//创建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.livingTargetPositions.Count; i++)
{
target = xmlDoc.CreateElement("target");
targetPosition = xmlDoc.CreateElement("targetPosition");
//设置InnerText值
targetPosition.InnerText = save.livingTargetPositions[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 --(targettarget -- (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 + "/StreamingFile" + "/byXML.txt"))
{
UIManager._instance.ShowMessage("保存成功");
}
}
结果如下
<save name="saveFile1">
<target>
<targetPosition>0</targetPosition>
<monsterType>2</monsterType>
</target>
<target>
<targetPosition>1</targetPosition>
<monsterType>1</monsterType>
</target>
<target>
<targetPosition>2</targetPosition>
<monsterType>1</monsterType>
</target>
<target>
<targetPosition>3</targetPosition>
<monsterType>1</monsterType>
</target>
<target>
<targetPosition>4</targetPosition>
<monsterType>3</monsterType>
</target>
<target>
<targetPosition>5</targetPosition>
<monsterType>2</monsterType>
</target>
<target>
<targetPosition>8</targetPosition>
<monsterType>0</monsterType>
</target>
<shootNum>2</shootNum>
<score>1</score>
</save>
9.读取游戏(XML)
private void LoadByXml()
{
string filePath = Application.dataPath + "/StreamingFile" + "/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.livingTargetPositions.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;
SetGame(save);
UIManager._instance.ShowMessage("");
}
else
{
UIManager._instance.ShowMessage("存档文件不存在!");
}
}