Skip to main content
 首页 » 资源教程 » Unity3D教程

Unity3D——游戏序列化

2016年09月09日 17:21:019070

说在前面

    序列化是为了将对象存储(或传输)到内存、数据库或文件中,把对象状态转化为一组字节的过程。换句话说:就是如何保存对象并恢复其状态以供后续使用。现在的游戏一般都离不开序列化,特别是一些大型游戏,因为游戏本身就非常大,每次版本更新就去重装一次显然不现实。而游戏系列化就能很好的解决这个矛盾,通过比对服务器上的文本数据来判断玩家是否需要更新。


实现

    以之前写过的一个简单的打飞碟游戏为基础,实现将其的序列化

    首先在Assets视图中创建文件夹Data,并将存放游戏版本与关卡信息的json文件,如下:

Unity3D——游戏序列化 Unity3D教程 第1张

Unity3D——游戏序列化 Unity3D教程 第2张


原先的关卡信息存放在GameController.cs中,现在已经序列化了,这个类原先的实现就没有用处的,可以将其实现清空,然后再在其后添加两个带有[SerializeField]符号的类,一个存放关卡信息,一个存放版本信息,用于类的可序列化:

[html] view plain copy
  1. [SerializeField]    
  2. public class GameInfo    
  3. {    
  4.     public string version;    
  5.     public int totalRound;    
  6.     
  7.     public static GameInfo CreateFromJSON(string json)    
  8.     {    
  9.         return JsonUtility.FromJson<GameInfo>(json);    
  10.     }    
  11. }    
  12.     
  13. [SerializeField]    
  14. public class LevelData    
  15. {    
  16.     public float speed;    
  17.     public int round;    
  18.     
  19.     public static LevelData CreateFromJSON(string json)    
  20.     {    
  21.         return JsonUtility.FromJson<LevelData>(json);    
  22.     }    
  23. }    



接着创建一个FileManager的cs脚本,用于处理文本的读写:

[html] view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using Com.Mygame;  
  4. using Com.GameControllers;  
  5.   
  6. public class FileManager : MonoBehaviour {  
  7.     public string url;  
  8.     private GameController sceneGameController.getInstance();  
  9.     void Awake()  
  10.     {  
  11.         scene = GameController.getInstance();  
  12.         scene.setFileManager(this);  
  13.         LoadGameInfoJson("disk_game.json"); // 获取游戏版本等信息  
  14.     }  
  15.     // 输入关卡文件名,启动协程读取文件  
  16.     public void loadLevelJson(string name)  
  17.     {  
  18.         url = "file://" + Application.dataPath + "/Data/" + name;  
  19.         StartCoroutine(LoadLevel());  
  20.     }  
  21.   
  22.     IEnumerator LoadLevel()  
  23.     {  
  24.         if (url.Length > 0)  
  25.         {  
  26.             WWW www = new WWW(url);  
  27.             yield return www;  
  28.             if (!string.IsNullOrEmpty(www.error))  
  29.                 Debug.Log(www.error);  
  30.             else  
  31.                 scene.stageLevel(www.text.ToString());  // 返回json字符串给scene  
  32.         }  
  33.     }  
  34.   
  35.     // 输入游戏信息文件名,启动协程读取文件  
  36.     public void LoadGameInfoJson(string name)  
  37.     {  
  38.         url = "file://" + Application.dataPath + "/Data/" + name;  
  39.         StartCoroutine(LoadGameInfo());  
  40.     }  
  41.   
  42.     IEnumerator LoadGameInfo()  
  43.     {  
  44.         if (url.Length > 0)  
  45.         {  
  46.             WWW www = new WWW(url);  
  47.             yield return www;  
  48.             if (!string.IsNullOrEmpty(www.error))  
  49.                 Debug.Log(www.error);  
  50.             else  
  51.                 scene.stageGameInfo(www.text.ToString());   // 返回json字符串给scene  
  52.         }  
  53.     }  
  54. }  


为了在屏幕上显示版本信息,因此需要更改UI脚本,类似这样:

Unity3D——游戏序列化 Unity3D教程 第3张

 另外,游戏的关卡是游戏过程中读取的,我将关卡信息放在rules.cs中,所以现在需要修改调用下一Round的函数:

[html] view plain copy
  1. public void passLever() {  
  2.             my = GameController.getInstance();  
  3.   
  4.             if (++lever > my._totalRound) {    
  5.                 lever = 1; // 循环    
  6.             }    
  7.             string file = "disk_level_" + lever.ToString() + ".json";    
  8.             my.getFileManager().loadLevelJson(file);    
  9.         }  

最后,还需要修改GameController.cs,比如添加FileManager的注册函数和调用函数;添加stageLevel和stageGameinfo用于接收json字符串并将其转化为对应的游戏参数:

[html] view plain copy
  1.        private FileManager _fileManager;  
  2.        public string _version;    
  3.        public void stageGameInfo(string json) {    
  4.         GameInfo data = GameInfo.CreateFromJSON(json);    
  5.             _version = data.version;    
  6.         _totalRound = data.totalRound;    
  7.     }  
  8. public void stageLevel(string json) {    
  9.         LevelData data = LevelData.CreateFromJSON(json);    
  10.         rule.speed = data.speed;  
  11.         rule.lever = data.round;   
  12.     }    
  13.       
  14. public FileManager getFileManager() {    
  15.         return _fileManager;    
  16.     }    
  17.        internal void setFileManager(FileManager ggo) {    
  18.         if (null == _fileManager) {    
  19.             _fileManager = ggo;    
  20.         }    
  21.     }   


最后看看简单效果:

Unity3D——游戏序列化 Unity3D教程 第4张


评论列表暂无评论
发表评论