Unity数据的存储——XML(二)

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;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41579634/article/details/88825797