天天看點

Unity3d遊戲開發之使用LitJson對float資料的支援處理

直接進入主題,下面是一個簡單例子。

/// <summary>
/// 需同步的玩家位置資訊
/// </summary>
[System.Serializable]
public struct PlayerPosition 
{
    public float x;
    public float y;
    public float z;
    //旋轉
    public float angle;
}
           
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LitJson;

/// <summary>
/// 位置同步
/// </summary>
public class SimplePlayPostionSync : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        SendPosition();
    }

    private void SendPosition() {
        PlayerPosition pos = new PlayerPosition
        {
            x = transform.position.x,
            y = transform.position.y,
            z = transform.position.z,
            angle = transform.rotation.eulerAngles.y
        };
        Debug.Log("初始值:" + pos.x + "--" + pos.y + "--" + pos.z + "--" + pos.angle);
        string json = JsonMapper.ToJson(pos);
        Debug.Log("Litjson序列化位置資料:" + json);
    }
}
           

然後運作,沒有得到想要的結果,報錯了:

JsonException: Max allowed object depth reached while trying to export from type System.Single

序列化不行,反序列化成float也會報錯。

立馬F3檢視,在JsonData類裡發現Litjson預設是不支援float類型的:

public JsonData(bool boolean);

public JsonData(double number);

public JsonData(int number);

public JsonData(long number);

public JsonData(object obj);

public JsonData(string str);

到這裡,有多種解決辦法:

①别用float,用double(需要轉換)

②換json庫(newtonjson, simplejson等等)

③不寫了(那是不可能的)

④本文方法:Litjson裡的兩個注冊函數

public static void RegisterExporter<T>(ExporterFunc<T> exporter);

public static void RegisterImporter<TJson, TValue>(ImporterFunc<TJson, TValue> importer);

根據粗陋的英語水準了解,RegisterExporter是将object序列化輸出為json string時起作用,RegisterImporter是将json string反序列化輸出為object時起作用。

那就簡單了,一番試驗下改代碼:

private void SendPosition() {
        PlayerPosition pos = new PlayerPosition
        {
            x = transform.position.x,
            y = transform.position.y,
            z = transform.position.z,
            angle = transform.rotation.eulerAngles.y
        };
        Debug.Log("初始值:" + pos.x + "--" + pos.y + "--" + pos.z + "--" + pos.angle);
        JsonMapper.RegisterExporter((float val, JsonWriter jw) =>
        {
            //jw.Write(val);//不能這樣寫,float精度不準确
            jw.Write(double.Parse(val.ToString()));
        });
        string json = JsonMapper.ToJson(pos);
        Debug.Log("Litjson序列化位置資料:" + json);

        JsonMapper.RegisterImporter((double val) => {
            return (float)val;
        });
        PlayerPosition pp = JsonMapper.ToObject<PlayerPosition>(json);
        Debug.Log("Litjson反序列化值:" + pp.x + "--" + pp.y + "--" + pp.z + "--" + pp.angle);
    }
           

運作,正确,ojbk!

Unity3d遊戲開發之使用LitJson對float資料的支援處理

 注:附上float精度問題導緻轉為json字元串時的結果

Unity3d遊戲開發之使用LitJson對float資料的支援處理

由于注冊函數是靜态方法,全局調用一次就行了。同理,有其他類型轉換出錯的,都可以像這樣進行事件注冊來達到想要的效果。