Unity实现json格式的序列化并发布

关于Unity实现json的反序列化并发布


先上个发布在桌面上的小应用效果图
虽然丑,但是毕竟心血
Unity实现json格式的序列化并发布_第1张图片


一:什么是序列化

简单说就是把一个内存对象变为与地址无关的可传输的数据格式
通常是文本格式;反序列化反之。
详情请看中山大学潘茂林老师的课件:

http://ss.sysu.edu.cn/~pml/se347/11_publish_serialization.html

实现序列化很重要,有助于我们更新游戏,因为更新游戏不允许修改exe文件。
我们只能通过向用户传一系列的系列化后的文件。
然后再反序列化更新游戏中内存对象的属性。


二:unity中json格式的序列化

unity是支持将json格式的文件来反序列化

首先,我们通过unity中WWW类型来打开json文件。
找到json文件的url,

string url = "json文件所在的地址" 

然后新建WWW类型打开url地址对应的json文件

WWW www = new WWW(url);
String json = www.text.ToString();

现在我们得到了一个json格式的字符串
利用unity自带的反序列化来解读字符串

[SerializeField] //这是最新版unity表示可序列化类的标签
public class Data
{
    public int data1;
    public float data2;
    public static Data CreateFromJSON(string json)
    {
        return JsonUtility.FromJson(json);
    }
}

现在,我们只要调用类中的CreateFromJSON函数

Data _data = Data.CreateFromJSON(json);

然后,我们就可以得到一个类的实例_data
访问数据,只需要下面操作

int json_data1 = _data.data1;
float json_data2 = _data.data2;
Debug.Log(json_data1);
Debug.Log(json.data2);

三:具体代码例子(序列化的具体应用)

这里只贴出游戏中的json文件读取,以及反序列化实现的2个类
其他代码,可以去我最下面提供的网盘地址下载我的demo

反序列的实现类:Sence_control

namespace My_Game_Scene {
    public struct GameData//定义一个结构体类型存储相应内存对象的属性
    {
        public int y_force;
        public float next_time;
        public Color flys_color;
    }

    public class SceneControl : System.Object
    {
        private static SceneControl _instance = null;
        private FileManager _fm;
        public int level = 1;
        public GameData game_data; //存储data的结构体
        public string game_version;
        public int game_total_round;

        public static SceneControl GetInstance() {
            if (_instance == null)
                _instance = new SceneControl();
            return _instance;
        }

        public FileManager GetFM()
        {
            return _fm;
        }

        public void SetFM(FileManager fm)
        {
            _fm = fm;
        }

        public void stageGameInfo(string json)
        {
            GameInfo data = GameInfo.CreateFromJSON(json);
            game_version = data.version;
            game_total_round = data.totalRound;
        }

        public void nextRound()
        {
            if (level > game_total_round)
            {
                level = 1; // 循环  
            }
            string file = "disk_level_" + level.ToString() + ".json";
            _fm.loadLevelJson(file);
        }

        public void stageLevel(string json) //实现反序列化的函数
        {
            LevelData data = LevelData.CreateFromJSON(json);//将json字符串进行反序列化
            game_data.y_force = data.y_force;
            game_data.next_time = data.next_time;
            game_data.flys_color = Color.HSVToRGB(data.f_c_a, data.f_c_b, data.f_c_c);
        }
    }
}

[SerializeField]//可序列化类的标签
public class LevelData
{
    public int y_force;
    public float next_time;
    public float f_c_a;
    public float f_c_b;
    public float f_c_c;
    public static LevelData CreateFromJSON(string json)
    {
        return JsonUtility.FromJson(json);
    }
}

[SerializeField]
public class GameInfo
{
    public string version;
    public int totalRound;
    public static GameInfo CreateFromJSON(string json)
    {
        return JsonUtility.FromJson(json);
    }
}
public class Scene_Control : MonoBehaviour {}

读取json文件的实现类:FileManager

using UnityEngine;
using System.Collections;
using My_Game_Scene;

public class FileManager : MonoBehaviour {
    private SceneControl sc;//场景管理者(单例),在sc中实现反序列化
    public string url;//json文件的地址

    void Awake() {
        sc = SceneControl.GetInstance();
        sc.SetFM(this);
        LoadGameInfoJson("game_info.json");
    }

    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
                sc.stageGameInfo(www.text.ToString()); //将其交给sc进行反序列化 
        }
    }

    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
                sc.stageLevel(www.text.ToString());  // 返回json字符串给scene  
        }
    }
}

游戏发布

Unity实现json格式的序列化并发布_第2张图片

如图点击build and run,保存在桌面的打飞碟文件夹

这里注意,你发布了之后,发现之前辛辛苦苦打的json文件不见了

Unity实现json格式的序列化并发布_第3张图片

然后游戏运行就出现了bug,因为没有json文件读入,
内存对象的一些属性就全乱了。
经过很久的debug,发现,只要按照代码中写的m,在对应的_data
就是发布后储存数据的的文件夹里新建DATA放入我们的json文件
Unity实现json格式的序列化并发布_第4张图片
Unity实现json格式的序列化并发布_第5张图片
然后 exe文件就可以正常运行了。


五:更新游戏

经过上面的步骤,一旦想更新游戏,只要修改data中的json文件就可以了
因为我们向用户更新游戏的时候,虽然不允许修改exe文件
但是可以通过一些途径更改json文件。
也就说,我们只要像下图中更改json文件,就可以简单更新游戏了
Unity实现json格式的序列化并发布_第6张图片


六:游戏Demo

这网盘中,有整个打飞碟游戏的demo,以及生成的exe文件及其文件夹
读者可以去下载
链接: http://pan.baidu.com/s/1i4BtoZ7 密码: rvdu


你可能感兴趣的:(Unity3D,c#,unity,json,c#,代码实现)