• Unity3d存档例子


    这是场景存储的信息类,创建好不管它

    using UnityEngine; 
    using System.Collections; 

    [SerializeField]public class Sence//场景存储的变量放这个类里 

    {

          Public Vector3 cubePosion; //Cube位置信息

    }

     

    这是GameDataManager类,游戏日志控制器。

    using UnityEngine; 
    using System.Collections; 
    using System.IO; 
    using System.Collections.Generic; 
    using System; 
    using System.Text; 
    using System.Xml; 
    using System.Security.Cryptography; 
    //GameData,储存数据的类,把需要储存的数据定义在GameData之内就行// 
    public class GameData 

        //密钥,用于防止拷贝存档// 
        public string key; 


        //下面是添加需要储存的内容// 
        public bool isDu;//点击读档为True,加载场景后为False

        //场景存储内容
        public Sence s;

        public GameData() 
        { 
            s = new Sence ();//存储内容初始化,只能放构造函数
            isDu = false;
        } 

    //管理数据储存的类// 
    public class GameDataManager:MonoBehaviour 

        private string dataFileName ="tankyWarData.dat";//存档文件的名称,自己定// 
        private  XmlSaver xs = new XmlSaver(); 

        public  GameData gameData; 

        public void Awake() 
        { 
            gameData = new GameData(); 
            //设定密钥,根据具体平台设定// 
            gameData.key = SystemInfo.deviceUniqueIdentifier; 
            Load(); 
        } 

        //存档时调用的函数// 
        public  void Save() 
        { 
            string gameDataFile = GetDataPath() + "/"+dataFileName; 
            string dataString= xs.SerializeObject(gameData,typeof(GameData)); 
            xs.CreateXML(gameDataFile,dataString); 
        } 

        //读档时调用的函数// 
        public  void Load() 
        { 
            string gameDataFile = GetDataPath() + "/"+dataFileName; 
            if(xs.hasFile(gameDataFile)) 
            { 
                string dataString = xs.LoadXML(gameDataFile); 
                GameData gameDataFromXML = xs.DeserializeObject(dataString,typeof(GameData)) as GameData; 

                //是合法存档// 
                if(gameDataFromXML.key == gameData.key) 
                { 
                    gameData = gameDataFromXML; 
                } 
                //是非法拷贝存档// 
                else 
                { 
                    //留空:游戏启动后数据清零,存档后作弊档被自动覆盖// 
                } 
            } 
            else 
            { 
                if(gameData != null) 
                    Save(); 
            } 
        } 

        //获取路径// 
        private static string GetDataPath() 
        { 
            // Your game has read+write access to /var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/Documents 
            // Application.dataPath returns ar/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/myappname.app/Data              
            // Strip "/Data" from path 
            if(Application.platform == RuntimePlatform.IPhonePlayer) 
            { 
                string path = Application.dataPath.Substring (0, Application.dataPath.Length - 5); 
                // Strip application name 
                path = path.Substring(0, path.LastIndexOf('/'));  
                return path + "/Documents"; 
            } 
            else 
                //    return Application.dataPath + "/Resources"; 
                return Application.dataPath; 
        } 

    这是XmlSaver类,用于管理XML。创建就可以,不需要操作。


    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 :MonoBehaviour{    
        //内容加密 
        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; 
        } 

    这是场景里的存储内容

    using UnityEngine;
    using System.Collections;

    [SerializeField]public class Sence{
        //Cube的存储内容
        public Vector3 cubePosion;//正方形的坐标

    }

    场景如图

     

    场景里有一个Cube,两个4方形,两个4方形是为了方便对照Cube的位置。

     

    调整摄像机角度,能看到Cube。

    建一个空物体,用来加载GameDataManager(游戏日志控制器),和XmlSaver类。

     

    给Cube写一个保存读取类(游戏日志控制器是对游戏数据的操作,所以只能改变部分数据,这个类用于改变Cube的部分数据)

    using UnityEngine;
    using System.Collections;

    public class SaveCube : MonoBehaviour {

        public void Save(){//保存Cube的部分数据,这里保存Cube的位置信息
            
            GameObject cube = GameObject.Find("Cube");//获得Cube对象

            GameObject gameDataManager = GameObject.Find ("GameDataManager");//获得GameDataManager(游戏控制器)对象
            GameDataManager g = gameDataManager.GetComponent<GameDataManager>();//获得GameDataManager(游戏控制器)脚本

            g.gameData.s.cubePosion = cube.transform.position;//保存Cube的位置
        }

        public void Load(){//场景开始时加载游戏对象

            GameObject cube = GameObject.Find("Cube");//获得Cube对象

            GameObject gameDataManager = GameObject.Find ("GameDataManager");//获得GameDataManager(游戏控制器)对象
            GameDataManager g = gameDataManager.GetComponent<GameDataManager>();//获得GameDataManager(游戏控制器)脚本

            if(g.gameData.isDu == true){//如果是读档状态
                cube.transform.position = g.gameData.s.cubePosion;//读取Cube的位置,并赋值给Cube
            }
        }

    }

    这是以场景为单位的(场景初始化,游戏日志保存)

    using UnityEngine;
    using System.Collections;

    public class SenceData : MonoBehaviour {


        void Start () {//初始化场景
            //Cube信息的初始化
            SaveCube sc = gameObject.GetComponent<SaveCube>();
            sc.Load ();


            //末尾设置默认不读挡
            GameObject gameDataManager = GameObject.Find ("GameDataManager");
            GameDataManager g = gameDataManager.GetComponent<GameDataManager> ();
            g.gameData.isDu = false;
            g.Save ();
        }
        public void Save (){//存档数据
            //Cube信息的保存
            SaveCube sc = gameObject.GetComponent<SaveCube>();
            sc.Save();


        }
    }

    建一个空物体用于加载SenceData类,SaveCube类,如图

     

    这是选择读档 存档 默认场景的UI类(就是用于用户操作的按钮设置)

    using UnityEngine;
    using System.Collections;

    public class UI : MonoBehaviour {

        private GameDataManager g;//定义GameDataManager(游戏控制器)脚本
        private SenceData s;//定义SenceData(场景加载器)脚本

        public int senceNum;

        // Use this for initialization
        void Start () {
            GameObject gameDataManager = GameObject.Find ("GameDataManager");//获得GameDataManager(游戏控制器)对象
            g = gameDataManager.GetComponent<GameDataManager>();//获得GameDataManager(游戏控制器)脚本
            GameObject senceData = GameObject.Find ("SenceData");//获得SenceData(场景加载器)对象
            s = senceData.GetComponent<SenceData>();//获得SenceData(场景加载器)脚本
        }

        void OnGUI(){
            if(GUI.Button (new Rect(Screen.width/2-110,Screen.height/2-150,50,50),"存")){
                s.Save ();//场景提交数据
                g.Save ();//日志保存
            }
            if(GUI.Button (new Rect(Screen.width/2+110,Screen.height/2-150,50,50),"读")){
                g.gameData.isDu = true;//设置为可读档状态
                g.Save ();//日志保存为可读档状态

                UnityEngine.SceneManagement.SceneManager.LoadScene (senceNum);//加载场景
            }
            if(GUI.Button (new Rect(Screen.width/2-50,Screen.height/2-150,100,50),"默认场景")){
                UnityEngine.SceneManagement.SceneManager.LoadScene (senceNum);//加载场景
            }
        }
    }

    建一个空物体加载UI类,如图

     

    这里我把SenceNum设置成0

    保存场景,如图

     

    然后File ->Build Settings..->Add Open Sence,如图

     

    这个存档的例子就做好了

    运行时图为

     

    保持运行,通过场景移动Cube,如图

    回到游戏,点击存按钮,再点读。

    获取了保存的位置,再点默认回到了原来的点。自己看看想想原理。

  • 相关阅读:
    如何让elementui 侧边栏的高度站整个屏幕
    渐变色 + 屏幕缩小自动产生滚动条
    css写一条线 鼠标悬浮的时候从中间向两边延申
    vue路由之间带参数跳转params与query的区别
    Oracle_11g_x64的安装与完全卸载
    类型不匹配 java.lang.IllegalArgumentException : argument type mismatch
    java.io.NotSerializableException 没有序列化异常
    MyBatis 面试题
    Navicat连接远程主机(腾讯云服务器)的mysql失败,解决(为需要远程登录的用户赋予权限)
    如何把web项目部署到Linux云服务器(详细流程)
  • 原文地址:https://www.cnblogs.com/wowanyasuo/p/5976876.html
Copyright © 2020-2023  润新知