DataBases : 信息基类,存储欲存档的信息。对于各种存档信息可以由此派生。派生类一般不含方法。
DataItems : 信息项基类,操作信息类。为Manager提供所有DataBse。
GameData : 游戏信息,所有需要存档的DataBase都需要存储在改类List中。
GameDataManager : 游戏存档类,提供Save()和Load()接口
实质就是将该类的gamedata对象序列化保存。
XmlSave : Xml序列化类。
PlayerData : 继承DataBase,包含Player需要存档的属性,即坐标,旋转,大小。
PlayerDataItem :继承DataItem, 主要负责存档时将属性放入PlayerData,读档时利用PlayerData对Player设置属性。
TimeData : 继承DataBase,存储当前消耗时间信息。
TimeDataItem : 继承DataItem,主要负责存档时将属性放入TimeData,读档时利用TimeData对显示时间设置。
wasd控制角色前后左右移动,Q存档,E读档
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestDatas : MonoBehaviour {
void Start () {
//加载XML数据,加载场景
SceneRead.LoadSceneXML();
}
void Update () {
if (Input.GetKeyDown(KeyCode.Q))
{
Debug.Log("存档");
GameDataManagers._instance.Save();
}
if (Input.GetKeyDown(KeyCode.E))
{
Debug.Log("读档");
GameDataManagers._instance.Load();
List<DataBases> datas = GameDataManagers._instance.cloneData.datas;
for (int i = 0; i < datas.Count; i++)
{
GameObject go = GameObject.Find(datas[i].objName);
go.GetComponent<DataItems>().Load(datas[i]);
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//GameDatas,储存数据的类,把需要储存的诗句定义在GameDatas之内
public class GameDatas {
//密钥,用于防止拷贝存档
public string key;
//下面是添加需要存储的内容
public List<DataBases> datas = new List<DataBases>();
public void Registe(DataBases data)
{
datas.Add(data);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
public class GameDataManagers : MonoBehaviour {
public static GameDataManagers _instance;
//存档文件的路径和名称
private string dataFileName = "test/TestGame/TestSave1.data";
private XmlSaver xs = new XmlSaver();
public List<DataItems> items;
public GameDatas gameData;
public GameDatas cloneData;
private void Awake()
{
gameData = new GameDatas();
cloneData = new GameDatas();
_instance = this;
//设定密钥,根据具体平台设定
gameData.key = SystemInfo.deviceUniqueIdentifier;
}
//存档时调用的函数
public void Save()
{
string gameDataFile = GetDataPath() + "/" + dataFileName;
for (int i = 0; i < items.Count; i++)
{
items[i].Save();
}
string dataString = xs.SerializeObject(gameData, typeof(GameDatas));
xs.CreateXML(gameDataFile, dataString);
}
//读档时调用的函数
public void Load()
{
string gameDataFile = GetDataPath() + "/" + dataFileName;
if (xs.hasFile(gameDataFile))
{
string dataString = xs.LoadXML(gameDataFile);
GameDatas gameDataFromXML = xs.DeserializeObject(dataString, typeof(GameDatas)) as GameDatas;
//是合法存档
if (gameDataFromXML.key==gameData.key)
{
cloneData = gameDataFromXML;
}
//是非法拷贝存档
else
{
//留空:游戏启动后数据清零,存档后作弊档被自动覆盖
}
}
else
{
if (gameData!=null)
{
Save();
}
}
}
//获取路径
private static string GetDataPath()
{
return Application.dataPath;
}
public void Registe(DataItems item)
{
items.Add(item);
}
}
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using UnityEngine;
//在这里添加你的所有需要序列化的信息类
[XmlInclude(typeof(PlayerDatas))]
[XmlInclude(typeof(TimeDatas))]
[XmlInclude(typeof(CubeDatas))]
public class DataBases
{
public string objName;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class DataItems : MonoBehaviour {
public DataBases item;
public virtual void Start()
{
item.objName = this.gameObject.name;
GameDataManagers._instance.gameData.Registe(item);
GameDataManagers._instance.Registe(this);
}
public abstract void Save();
public abstract void Load(DataBases data);
}
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
public float walkSpeed;
public float rotaSpeed;
private Rigidbody rigid;
private Animation anim;
void Awake()
{
rigid = GetComponent<Rigidbody>();
anim = GetComponent<Animation>();
}
void Update () {
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Quaternion rota = Quaternion.LookRotation(transform.forward * (v + 1.5f) + transform.right * h);
transform.rotation = Quaternion.Slerp(transform.rotation, rota, rotaSpeed * Time.deltaTime);
transform.position = Vector3.Lerp(transform.position, transform.forward * walkSpeed * v * Time.deltaTime + transform.position, 50 * Time.deltaTime);
if(Mathf.Abs(v) > 0.3f)
{
anim.CrossFade("Run");
}
else
{
anim.Stop();
}
}
}
//=========================================================================================================
//Note: XML processcing, can not save multiple-array!!!
//Date Created: 2012/04/17 by 风宇冲
//Date Modified: 2012/04/19 by 风宇冲
//=========================================================================================================
using UnityEngine;
using System.Collections;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System;
public class XmlSaver
{
//内容加密
public string Encrypt(string toE)
{
//加密和解密采用相同的key,具体自己填,但是必须为32位//
byte[] keyArray = UTF8Encoding.UTF8.GetBytes("12348578902223367877723456789012");
RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.Mode = CipherMode.ECB;
rDel.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = rDel.CreateEncryptor();
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toE);
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
//内容解密
public string Decrypt(string toD)
{
//加密和解密采用相同的key,具体值自己填,但是必须为32位//
byte[] keyArray = UTF8Encoding.UTF8.GetBytes("12348578902223367877723456789012");
RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.Mode = CipherMode.ECB;
rDel.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = rDel.CreateDecryptor();
byte[] toEncryptArray = Convert.FromBase64String(toD);
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return UTF8Encoding.UTF8.GetString(resultArray);
}
public string SerializeObject(object pObject, System.Type ty)
{
string XmlizedString = null;
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(ty);
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, pObject);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
return XmlizedString;
}
public object DeserializeObject(string pXmlizedString, System.Type ty)
{
XmlSerializer xs = new XmlSerializer(ty);
MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
return xs.Deserialize(memoryStream);
}
//创建XML文件
public void CreateXML(string fileName, string thisData)
{
string xxx = Encrypt(thisData);
StreamWriter writer;
writer = File.CreateText(fileName);
writer.Write(xxx);
writer.Close();
}
//读取XML文件
public string LoadXML(string fileName)
{
StreamReader sReader = File.OpenText(fileName);
string dataString = sReader.ReadToEnd();
sReader.Close();
string xxx = Decrypt(dataString);
return xxx;
}
//判断是否存在文件
public bool hasFile(String fileName)
{
return File.Exists(fileName);
}
public string UTF8ByteArrayToString(byte[] characters)
{
UTF8Encoding encoding = new UTF8Encoding();
string constructedString = encoding.GetString(characters);
return (constructedString);
}
public byte[] StringToUTF8ByteArray(String pXmlString)
{
UTF8Encoding encoding = new UTF8Encoding();
byte[] byteArray = encoding.GetBytes(pXmlString);
return byteArray;
}
}