在遊戲設計中,序列化是一件很核心的東西。程序員
序列化就是把一個內存對象變爲與地址無關的可傳輸的數據格式,一般是文本格式。若是遊戲沒有實現序列化,那麼當遊戲須要進行版本更新時,將會浪費玩家大量的時間。尤爲對於大型遊戲來講,這種浪費是不可想象的。實現遊戲序列化設計,經過數據驅動設計,使得遊戲代碼更加穩固 (robustness)。咱們能夠經過改變數據,實現遊戲規則、 場景佈局、遊戲難度的動態改變,而不要程序員的參與。 讓遊戲發佈後,運維與設計師進行」後設計」 (Post-Design) 成爲可能。json
所以此次咱們就來實現一個簡單的序列化設計。運維
步驟:dom
首先,咱們選擇的是json文原本實現,由於Unity已內置json支持。函數
咱們將須要的json文本,放入到Assets下的data(自建)文件夾中。佈局
由於咱們只是一個簡單的序列化實現,因此咱們要實現的序列化任務是部分,主要實現的是不一樣關卡中飛碟的特性。this
替代的是如下部分:url
switch (round) { case 0: { newDisk.GetComponent<DiskData>().color = Color.blue; newDisk.GetComponent<DiskData>().speed = 4.0f; float RanX = UnityEngine.Random.Range(-1f, 1f) < 0 ? -1 : 1; newDisk.GetComponent<DiskData>().direction = new Vector3(RanX, 1, 0); newDisk.GetComponent<Renderer>().material.color = Color.blue; break; } case 1: { newDisk.GetComponent<DiskData>().color = Color.red; newDisk.GetComponent<DiskData>().speed = 6.0f; float RanX = UnityEngine.Random.Range(-1f, 1f) < 0 ? -1 : 1; newDisk.GetComponent<DiskData>().direction = new Vector3(RanX, 1, 0); newDisk.GetComponent<Renderer>().material.color = Color.red; break; } case 2: { newDisk.GetComponent<DiskData>().color = Color.black; newDisk.GetComponent<DiskData>().speed = 8.0f; float RanX = UnityEngine.Random.Range(-1f, 1f) < 0 ? -1 : 1; newDisk.GetComponent<DiskData>().direction = new Vector3(RanX, 1, 0); newDisk.GetComponent<Renderer>().material.color = Color.black; break; } }
如今,咱們能夠用序列化的方式,來取代它們。.net
添加兩個帶有[SerializeField] 符號的類,用來對json數據進行序列化。[Serializable]標籤,說明這個類能夠被序列化。一個是用來存放關卡信息,另外一個用來存放版本信息。json文件的數據要與這個類的內容對應起來:設計
[SerializeField] public class GameInfo { public string version; public int totalRound; public static GameInfo CreateFromJSON(string json) { return JsonUtility.FromJson<GameInfo>(json); } } [SerializeField] public class LevelData { public string color1; public string color2; public float speed; public static LevelData CreateFromJSON(string json) { return JsonUtility.FromJson<LevelData>(json); } }
而後設計讀取json文件的FileManager類:
using UnityEngine; using System.Collections; using Com.Mygame; public class FileManager : MonoBehaviour { public string url; SceneController scene = SceneController.getInstance(); void Awake() { scene.setFileManager(this); // 獲取遊戲版本信息 LoadGameInfoJson("game_info.json"); } // 傳入文件名,啓動協程讀取文件 public void loadLevelJson(string name) { url = "file://" + Application.dataPath + "/Data/" + name; StartCoroutine(LoadLevel()); } IEnumerator LoadLevel() { if (url.Length > 0) { WWW www = new WWW(url); yield return www; if (!string.IsNullOrEmpty(www.error)) Debug.Log(www.error); else scene.stageLevel(www.text.ToString()); // 返回json字符串給scene } } // 傳入遊戲信息文件名,啓動協程讀取文件 public void LoadGameInfoJson(string name) { url = "file://" + Application.dataPath + "/Data/" + name; StartCoroutine(LoadGameInfo()); } IEnumerator LoadGameInfo() { if (url.Length > 0) { WWW www = new WWW(url); yield return www; if (!string.IsNullOrEmpty(www.error)) Debug.Log(www.error); else scene.stageGameInfo(www.text.ToString()); // 返回json字符串給scene } } }
爲了記錄下版本的信息,以及關卡數,咱們須要加多兩個變量來存儲這兩個信息:
private string _version; private int _totalRound;
另外還要修改接口函數信息:
public interface IQueryStatus { bool isCounting(); bool isShooting(); int getRound(); int getPoint(); int getEmitTime(); int getTotalRound (); string getVersion (); } public int getTotalRound () { return _totalRound; } public string getVersion () { return _version; }
同時,遊戲的關卡是遊戲過程當中讀取的,因此修改sceneController的nextRound()方法:
public void nextRound() { _point = 0; if (++_round > _totalRound) { _round = 1; // 循環 } string file = "disk_level_" + _round.ToString() + ".json"; _fileManager.loadLevelJson(file); }
而後,補全stageLevel和stageGameInfo兩個序列化json實例後轉化爲相應的遊戲參數的方法:
public void stageLevel(string json) { LevelData data = LevelData.CreateFromJSON(json); Color color1; if (!ColorUtility.TryParseHtmlString(data.color1, out color1)) { color1 = Color.gray; } Color color2; if (!ColorUtility.TryParseHtmlString(data.color2, out color2)) { color2 = Color.gray; } float speed = data.speed; _gameModel.setting(color1, speed, color2); } public void stageGameInfo(string json) { GameInfo info = GameInfo.CreateFromJSON(json); _version = info.version; _totalRound = info.totalRound; }
此時運行遊戲,就能夠發現遊戲經過讀取文檔來和以前同樣運行了:
咱們再經過添加text,和修改useInterface,就能夠將版本信息也顯示出來。
參考連接:http://blog.csdn.net/simba_scorpio/article/details/51471161