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!

 注:附上float精度问题导致转为json字符串时的结果

由于注册函数是静态方法,全局调用一次就行了。同理,有其他类型转换出错的,都可以像这样进行事件注册来达到想要的效果。

  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值