Unity实用小工具或脚本——读写Json工具

一、前言

      在Unity中读写Json文件已经有非常好的工具,可以将Json文件和结构体数据进行相互转换,如图1所示,在Unity Asset Store中搜JSON.NET可以找到该插件,非常好用。我在此插件的基础上,融合了Windows的文件窗口,即打开和存储Json文件的时候可

图1

以获取Windows的窗口,选择保存和读取Json文件的路径。最后,实现了在Android上的读写Json文件。

二、实现

2.1、实现读写文件的窗口

代码如下:该类提供了一个Open_WindowFile方法,当参数"isSaveFile"为true时弹出窗口保存文件,false时弹出窗口打开文件,默认为false。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;//调用外部库,需要引用命名空间
using System;
using System.Threading;

public class Global_Windows  {

    public static Global_Windows M_Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new Global_Windows();
            }
            return _instance;
        }
    }
    private openFileName ofn = new openFileName();
    private static Global_Windows _instance;

    [DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern int MessageBox(IntPtr handle, String message, String title, int type);//具体方法
    [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern bool GetOpenFileName([In, Out] openFileName ofn);
    [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern bool GetSaveFileName([Out, In] openFileName ofn);

    /// <summary>
    /// 打开某个格式的文件,并返回该文件的地址
    /// </summary>
    /// <param name="dataType">该文件的格式</param>
    /// <param name="isSaveFile">true为保存文件,false为只是打开文件,默认为false</param>
    /// <returns></returns>
    public string Open_WindowFile(string dataType,bool isSaveFile=false)
    {
        string tempURL = string.Empty;
        ofn.structSize = Marshal.SizeOf(ofn);
        ofn.filter = dataType+"\0*."+ dataType + "*\0\0";
       // ofn.filter = "json\0*.json*\0\0";
        ofn.file = new string(new char[256]);
        ofn.maxFile = ofn.file.Length;
        ofn.fileTittle = new string(new char[64]);
        ofn.maxFileTittle = ofn.fileTittle.Length;
        string path = Application.streamingAssetsPath;
        path = path.Replace('/', '\\');
        ofn.initialDir = path;
        ofn.tittle = "Open Project";
        ofn.defExt = dataType;
        ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;

        if (isSaveFile&& GetSaveFileName(ofn))
        {
            tempURL = ofn.file;
        }
        else if(!isSaveFile&&GetOpenFileName(ofn))
        {
            tempURL = ofn.file;
        }
        return tempURL;
       
    }
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class openFileName
{

    public int structSize = 0;
    public IntPtr digOwner = IntPtr.Zero;
    public IntPtr instance = IntPtr.Zero;
    public String filter = null;
    public String customFilter = null;
    public int maxCustFilter = 0;
    public int filterIndex = 0;
    public String file = null;
    public int maxFile = 0;
    public String fileTittle = null;
    public int maxFileTittle = 0;
    public String initialDir = null;
    public String tittle = null;
    public int flags = 0;
    public short fileoffset = 0;
    public short fileExtension = 0;
    public String defExt = null;
    public IntPtr custData = IntPtr.Zero;
    public IntPtr hook = IntPtr.Zero;
    public String templataName = null;
    public IntPtr reservedPtr = IntPtr.Zero;
    public int resveredInt = 0;
    public int flagsEx = 0;
}

2.2、实现Json文件的读写

代码如下:保存Json文件的时候先打开窗口获取保存文件的类型和路径,然后将结构体数据序列化成字符串,使用JsonConvert.SerializeObject方法将数据序列化。下面的代码可以序列化结构体中的数组或列表。读取Json文件的时候,首先会判断路径是否为

    /// <summary>
    /// 将结构体数据保存成JSON文件
    /// </summary>
    /// <param name="JSONFilePath"></param>
    /// <param name="data"></param>
    public static bool SaveData_JSON(object data)
    {
        bool isSaveSucced = true;
        string JSONFilePath = Global_Windows.M_Instance.Open_WindowFile("json", true);
        #region 将结构体添加数据转换成JSON文件并存储
        try
        {
            FileInfo file = new FileInfo(JSONFilePath);
            //判断有没有文件,有则打开文件,,没有创建后打开文件
            StreamWriter sw = file.CreateText();
            string json = string.Empty;
            var settings = new JsonSerializerSettings()
            {
                TypeNameHandling = TypeNameHandling.All
            };
            json = JsonConvert.SerializeObject(data, settings);
            //   Debug.Log(json);
            //将转换好的字符串存进文件,
            sw.WriteLine(json);
            //注意释放资源
            sw.Close();
            sw.Dispose();
        }
        catch (Exception e)
        {
            Debug.Log(e.Message);
            isSaveSucced = false;
        }
        return isSaveSucced;
        #endregion
    }
    /// <summary>
    /// 读取文件夹里的JSON文件,并转换成对应的结构体,
    /// 默认没有路径的会自动打开文件夹选择窗口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static T ReadData_JSON<T>(string jsonURL = null)
    {
        T tempT = default(T);
        string JSONFilePath = jsonURL;
#if UNITY_STANDALONE_WIN || UNITY_EDITOR
        if (null == JSONFilePath)
        {
            JSONFilePath = Global_Windows.M_Instance.Open_WindowFile("json", false);
        }
#endif
        try
        {
            string tempStrData = string.Empty;
            //#if UNITY_STANDALONE_WIN || UNITY_EDITOR
            //            StreamReader sr = new StreamReader(JSONFilePath, Encoding.UTF8);//安卓平台不能使用这个读取只能使用www
            //            tempStrData = sr.ReadToEnd();
            WWW www = new WWW(JSONFilePath);
            while (!www.isDone)
            {
                // Debug.Log("正在读取!");
            }
            tempStrData = www.text;
            if (tempStrData.Length == 0 || string.Empty == tempStrData || null == tempStrData)
            {
#if UNITY_STANDALONE_WIN || UNITY_EDITOR
                Global_Windows.MessageBox(IntPtr.Zero, "JSON文件内容为空!", "确认", 0);
#endif
                Debug.Log("JSON文件内容为空!");
                return tempT;
            }
            var settings = new JsonSerializerSettings()
            {
                TypeNameHandling = TypeNameHandling.All
            };
            tempT = JsonConvert.DeserializeObject<T>(tempStrData, settings);
            //   Debug.Log(tempStrData);
        }
        catch (Exception e)
        {
            Debug.Log(e.Message);
#if UNITY_STANDALONE_WIN || UNITY_EDITOR
            Global_Windows.MessageBox(IntPtr.Zero, "读取JSON异常" + e.Message, "确认", 0);
#endif
            return tempT;
        }
        //  Global_Windows.MessageBox(IntPtr.Zero, "读取JSON数据成功", "确认", 0);
        return tempT;
    }

空,如果为空就开启窗口读取选择Json文件读取,如果不为空则不弹窗直接读取,非常方便。 另外,读写数据异常的时候会弹出Windows的消息窗口,代码如下:

 Global_Windows.MessageBox(IntPtr.Zero, "读取JSON异常" + e.Message, "确认", 0);

这个窗口时独立于Unity的,如果想单独使用在工程中也可以直接像上面那样调用。 

2.3、规范Json文件的保存路径

为了将Json文件的读写路径都统一到指定的路径下,还需要增加一个统一路径的代码,如下:这个路可以在安卓系统上运行且读写Json文件,在Winddows下的路径为和工程同级目录

    /// <summary>
    /// 获取跟工程相同目录的路径,如“E:/ZXB/MyProject/Asset/",去掉后面两个就得到和工程同级的目录为:“E:/ZXB”
    /// </summary>
    /// <returns></returns>
    private static string GetCurProjectFilePath()
    {
        string strPath = string.Empty;
#if UNITY_ANDROID
        strPath = "file:///storage/emulated/0/";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
        string[] strTempPath = Application.dataPath.Split('/');
        //去掉后面两个,获取跟工程相同目录的路径,如“E:/ZXB/MyProject/Asset/",去掉后面两个就得到和工程同级的目录为:“E:/ZXB”
        for (int i = 0; i < strTempPath.Length - 2; i++)
        {
            strPath += strTempPath[i] + "/";
        }
#endif
        return strPath;
    }

 

三、总结

3.1、考虑Json文件序列化数组或列表的时候要注意参数设置为TypeNameHandling.All;

3.2、安卓平台读取Json文件的时候只能用WWW类来获取。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值