写点什么

Unity 之 转微信小游戏本地数据存储

作者:陈言必行
  • 2023-04-13
    辽宁
  • 本文字数:2343 字

    阅读完需:约 8 分钟

前言

近期在将 Unity 转换为小游戏的时候发现在读写本地文件的时候,使用Application.persistentDataPath缓存路径来保存文件失败,原因是 WebGL 的平台限制。所以导致了原有读写本地文件的代码需要根据平台进行修改。

一种最简单的方式就是将原来存储到文件中的内容,在 WebGL 平台使用PlayerPrefs来存储。比如这样的写法:


使用PlayerPrefs的存在第一次读取慢的问题,可以使用微信小游戏的插件进行添加用到的 Key。使用方式:微信小游戏 -> PlayerPrefs 优化:


所以当需要存储文件很多或者数据很多的时候,我们还是希望在尽量不修改原有的读写逻辑的情况下进行完成文件的读写。所以微信给我们提供了WX.env.USER_DATA_PATH


微信小游戏读写本地文件

Unity 转成微信小游戏以后File.WriteAllTextFile.ReadAllText由于路径问题不生效。

改为使用微信小游戏插件提供的路径即可,插件中的代码:


示例代码如下:

using System;using System.Collections;using System.Collections.Generic;using System.IO;using UnityEngine;using WeChatWASM;
public class SaveFile : MonoBehaviour{    // 文件类型    private PlayerData m_PlayerData;
    // 文件名称    private string fileName = "/PlayerData.txt";
    private void OnGUI()    {        if (GUI.Button(new Rect(100, 100, 200, 200), "读取文件"))        {            LoadPlayerData();        }
        if (GUI.Button(new Rect(100, 400, 200, 200), "写入文件"))        {            WritePlayerData();        }    }
    /// <summary>    /// 读取文件    /// </summary>    private void LoadPlayerData()    {#if UNITY_WEBGL        WXFileSystemManager fs = WX.GetFileSystemManager();                // 判断是否存在目录        if (fs.AccessSync(WX.env.USER_DATA_PATH + fileName).Equals("ok"))        {            // 读取内容            string playerDataString = fs.ReadFileSync(WX.env.USER_DATA_PATH + fileName, "utf-8");            if (playerDataString != "")            {                m_PlayerData = LitJson.JsonMapper.ToObject<PlayerData>(playerDataString);            }        }
        Debug.Log($" 读取文件 姓名:{m_PlayerData.name} 年龄:{m_PlayerData.age}");#endif    }
    /// <summary>    /// 写入文件    /// </summary>    private void WritePlayerData()    {        m_PlayerData = new PlayerData();        m_PlayerData.name = "Czhenya";        m_PlayerData.age = 18;        Debug.Log($" 写入文件 姓名:{m_PlayerData.name} 年龄:{m_PlayerData.age}");
        string playerData = LitJson.JsonMapper.ToJson(m_PlayerData);#if UNITY_WEBGL        WXFileSystemManager fs = WX.GetFileSystemManager();        fs.WriteFileSync(WX.env.USER_DATA_PATH + fileName, playerData, "utf-8");#endif    }}
public class PlayerData{    public string name;    public int age;}
复制代码

测试结果:不校验是否存在本地目录就进行文件读取的报错:可以看到后面的读取和保存成功了:



PS:若只需要进行读取文件,在 StreamingAssets 文件夹下面的文件,在 WebGL 平台是可以通过UnityWebRequest来进行读取的。


WebGL 平台的一些限制

由于平台限制,有些功能在 WebGL 上是不支持的:

  • 不支持多线程,因为 JavaScript 不支持多线程,所以 System.Threading 命名空间下的类不要使用;

  • 不能直接使用 Socket,包括 System.Net 下的任何类型,以及 System.Net.Sockets 下的部分类型,以及 UnityEngine.Network,如果需要在 WebGL 平台使用网络功能,可以使用 WWW 或者 UnityWebRequest 这些都是基于 Http 协议的实现,如要需要高实时性,可以选择 WebSockets 或者 WebRTC;

  • WebGL 1.0 是基于 OpenGL ES 2.0,WebGL 2.0 基于 OpenGL ES 3.0,所以存在相应的限制;

  • WebGL 是 AOT(ahead of time,即静态编译平台,因此不能使用 System.Reflection.Emit 下的类型进行代码生成,IL2CPP 和 iOS 也是如此。


报错查看方法分享

转小游戏后可以通过打开调试模式在手机上看到报错日志,报错日志如下:

exception thrown : Runtiseerror : null function orfunction signature ismatch . Rurtimcerror : nullfunction or function signature mismatch

Mini Progran Error null function or function signature mismatchRuntimeerror: null function or function signaturemismatc

这两段报错是同一个问题触发的。第一次看到这种报错一脸茫然不知从何下手,再往下看两行就发现了我自己写的函数:ScreenRatiosFilter类中的Fit方法。都定位到报错方法了,之后的问题就不用我再说了吧。

既然你都看到这里了,还是告诉你一下秘诀吧:实在判断不出来是哪里报的错,而在编辑器又复现不出来,补日志,然后复现一下错误,这样就可以定位到具体报错行数了。

还遇到过一个奇怪的问题,一并记录一下。希望对你有所启发:一段游戏逻辑只在小游戏中报错,编辑器和其他端都没问题。后来加了一个try...catch捕获了一次,没做其他任何处理,然后竟然好用了...

发布于: 刚刚阅读数: 3
用户头像

陈言必行

关注

公号:开发同学留步 2019-03-12 加入

我是一个从事Unity游戏开发攻城狮,InfoQ&阿里云签约博主,CSDN博客专家,U3D论坛版主,6年开发经验,助你日常不加班。⽂章皆为从零到⼀的⼊⻔级教程,也有很多⼯作中遇到的问题解析。

评论

发布
暂无评论
Unity 之 转微信小游戏本地数据存储_Unity_陈言必行_InfoQ写作社区