Unity遊戲設計之實現序列化

在遊戲設計中,序列化是一件很核心的東西。程序員

序列化就是把一個內存對象變爲與地址無關的可傳輸的數據格式,一般是文本格式。若是遊戲沒有實現序列化,那麼當遊戲須要進行版本更新時,將會浪費玩家大量的時間。尤爲對於大型遊戲來講,這種浪費是不可想象的。實現遊戲序列化設計,經過數據驅動設計,使得遊戲代碼更加穩固 (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

相關文章
相關標籤/搜索