Unity 之 转微信小游戏本地数据存储方法分享

这篇具有很好参考价值的文章主要介绍了Unity 之 转微信小游戏本地数据存储方法分享。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题背景

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

一种最简单的方式就是将原来存储到文件中的内容,在WebGL平台使用PlayerPrefs来存储。比如这样的写法:
Unity 之 转微信小游戏本地数据存储方法分享

使用PlayerPrefs的存在第一次读取慢的问题,可以使用微信小游戏的插件进行添加用到的Key。使用方式:微信小游戏 -> PlayerPrefs优化:
Unity 之 转微信小游戏本地数据存储方法分享
微信插件中覆盖Unity中的API
Unity 之 转微信小游戏本地数据存储方法分享

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


微信小游戏读写本地文件

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

改为使用微信小游戏插件提供的路径即可,插件中的代码:
Unity 之 转微信小游戏本地数据存储方法分享

示例代码如下:

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("access: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;
}

测试结果:
不校验是否存在本地目录就进行文件读取的报错:
可以看到后面的读取和保存成功了:
Unity 之 转微信小游戏本地数据存储方法分享


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 也是如此。

Unity 之 转微信小游戏本地数据存储方法分享


一个创建目录的bug

经过测试发现,目前版本的SDK,不能递归创建目录的上级目录后再创建该目录。官方提供的
wxFileSystem.MkdirSync( WX.env.USER_DATA_PATH + @"/Test/Test1", true); 接口参数为:true时不好用,一层目录都创建不出来。只能将参数调整为false,一级一级创建目录。

创建多层目录返回结果,和使用时不存在目录的报错日志:

GetFileSystemManager 33333 res:mkdirSync:fail permission denied, open http:/usr/Storage/P

fs.js:130 Error: writeFileSync:fail permission denied, open http:/usr/Storage/P/tmp_Data1
at o (VM19 WAGame.js:1)

Unity 之 转微信小游戏本地数据存储方法分享
在微信开发工具中可以看到工程使用的本地路径:
Unity 之 转微信小游戏本地数据存储方法分享

Demo测试代码分享,里面实现了:实现了校验目录、创建目录、删除目录、校验文件、新建文件、读取文件和复制文件等功能。

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using WeChatWASM;

public class WXFileSave : MonoBehaviour
{
    private WXFileSystemManager wxFileSystem;

    private string rootPath;
    
    private string filePath;
    
    private string fileName;
    
    void Start()
    {
        wxFileSystem = new WXFileSystemManager();
        rootPath = WX.env.USER_DATA_PATH;
        filePath = "/Test/Data";
        fileName = "/text";
    }

    private void OnGUI()
    {
        if (GUI.Button(new Rect(10 ,10, 60, 60), "同步创建目录"))
        {
            CreateDirectoryMkdir(Path.Combine(rootPath, filePath));
        }

        if (GUI.Button(new Rect(10, 100, 60, 60), "创建目录"))
        {
            CreateDirectory(Path.Combine(rootPath, filePath));
        }
        
        if (GUI.Button(new Rect(10, 200, 60, 60), "校验目录"))
        {
            CheckDirectoryExists(Path.Combine(rootPath, filePath));
        }

        if (GUI.Button(new Rect(10, 300, 60, 60), "删除目录"))
        {
            DeleteDirectory(Path.Combine(rootPath, filePath));
        }       
       
        if (GUI.Button(new Rect(100 ,10, 60, 60), "写入文件"))
        {
            CreateFile(rootPath+ filePath + fileName, "测试写入内容");
        }
        
        if (GUI.Button(new Rect(200 ,10, 60, 60), "文件带后缀"))
        {
            CreateFile(rootPath+ filePath + fileName + ".txt", "测试写入内容");
        }

        if (GUI.Button(new Rect(100, 100, 60, 60), "读取文件"))
        {
            ReadFile(Path.Combine(rootPath, filePath + fileName));
        }
        
        if (GUI.Button(new Rect(100, 200, 60, 60), "校验文件"))
        {
            CheckFileExists(Path.Combine(rootPath, filePath));
        }

        if (GUI.Button(new Rect(100, 300, 60, 60), "复制文件"))
        {
           // CopyFile();
        }
    }

    // 校验目录是否存在
    public bool CheckDirectoryExists(string path)
    {
        Debug.Log($"校验路径:{path},是否存在{wxFileSystem.AccessSync(path).Equals("access:ok")}");
        return path != null && wxFileSystem.AccessSync(path).Equals("access:ok");
    }
    
    // 同步创建目录
    public void CreateDirectoryMkdir(string path)
    {
        // *** 参数为:true 不好用,不能递归创建目录的上级目录后再创建该目录。*** 
        // *** 只能一级一级创建目录 *** 
        string res = wxFileSystem.MkdirSync( WX.env.USER_DATA_PATH + @"/Test", false);
        Debug.Log($"同步创建目录{path}:创建结果:{res}");
    }

    /// <summary>
    /// 创建目录
    /// </summary>
    /// <param name="path"></param>
    public void CreateDirectory(string path)
    {
        Debug.Log($"同步创建目录:{path}");
        MkdirParam mkdirParam = new MkdirParam();
        //  *** 只能一级一级创建目录 *** 
        mkdirParam.dirPath = WX.env.USER_DATA_PATH + @"/Test1"; // path
        mkdirParam.recursive = true;
        wxFileSystem.Mkdir(mkdirParam);
        Debug.Log($"CreateDirectory 创建目录{path}");
    }

    // 删除目录
    public void DeleteDirectory(string path)
    {
        string res = wxFileSystem.UnlinkSync(path);
        Debug.Log($"DeleteDirectory 删除目录结果:{res}");
    }

    // 校验文件是否存在
    public bool CheckFileExists(string path)
    {
        Debug.Log($"校验文件是否存在:{path},是否存在{wxFileSystem.AccessSync(path).Equals("ok")}");
        return path != null && wxFileSystem.AccessSync(path).Equals("ok");
    }

    // 新建文件并写入内容
    public void CreateFile(string path, string content)
    {
        Debug.Log($"新建文件 路径:{path},写入内容:{content}");
        wxFileSystem.WriteFileSync(path, content);
    }

    // 读取文件内容
    public void ReadFile(string path)
    {
        // 读取文件内容
        wxFileSystem.ReadFile(new ReadFileParam()
        {
            filePath = path,
            encoding = "utf-8",
            success = (res) =>
            {
                Debug.Log("读取数据成功5555 **** :" + res.stringData);
            },
            fail = (res) =>
            {
                Debug.LogError("读取数据 报错5555 ---- :" + res.errMsg);
            }
        });
    }

    // 复制文件
    public void CopyFile(string sourcePath, string destPath)
    {
        UnityEngine.Debug.Log("复制文件:***** " + sourcePath);
        wxFileSystem.CopyFileSync(sourcePath, destPath);
        UnityEngine.Debug.Log("复制文件:/ " + sourcePath);
    }
}

报错查看方法分享

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

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

Unity 之 转微信小游戏本地数据存储方法分享

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

Unity 之 转微信小游戏本地数据存储方法分享

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

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

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

到了这里,关于Unity 之 转微信小游戏本地数据存储方法分享的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity项目转微信小游戏 微信小程序保姆教程,繁杂问题解决,及微信小游戏平台简单性能测试

    借着某人需求,做了一波简单的技术调研:将Unity项目转换为微信小游戏。 本文主要内容:Unity转换小游戏的步骤,遇到问题的解决方法,以及简单的性能测试对比 微信小游戏的限制 微信小游戏对程序包体大小有严格限制:首包必须小于2M,首包加分包(后加载)不得大于

    2024年02月05日
    浏览(67)
  • Unity 之 抖音小游戏本地数据最新存储方法分享

    抖音小游戏是一种基于抖音平台开发的小型游戏,与传统的 APP 不同,抖音小游戏运行在抖音客户端内部,可以通过抖音的分享、推荐等功能进行传播。在抖音小游戏开发过程中,文件存储系统是一个非常重要的组成部分,本文将详细介绍抖音小游戏文件存储系统的实现原理

    2024年02月11日
    浏览(55)
  • Unity 转微信小游戏Error building Player: Incompatible color space with graphics API

    Unity 开发 微信小游戏,进行转换小游戏时报Error building Player: Incompatible color space with graphics AP错误,主要原因是不兼容WEBGL2.0。 需要在 Unity Editor中File-Build settings-Player Settings中设置Color space为Gamma。默认值是Linear这需要WebGL2.0支持。 勾选选项WebGL2.0(Beta)选项。也可解决上述问题

    2024年02月14日
    浏览(41)
  • Unity - 微信小游戏

    总参考:Unity WebGL 微信小游戏适配方案(公测)   下载 Unity插件,并导入至游戏项目中,版本更新请查看更新日志 请查阅推荐引擎版本,安装时选择 WebGL 组件 最终选择 Unity2021.2.5f1c1 InstantGame 前往Node官网安装长期稳定版 之前已安装 v16.17.0 前往微信开发者工具下载安装 Stable

    2024年02月06日
    浏览(58)
  • unity微信小游戏——排行榜

    设置时记住排行榜唯一标识 此处建议使用官方案例的UI进行修改 minigame-unity-webgl-transform: Unity WebGL 微信小游戏适配方案 (gitee.com) DemoRanking这个项目就是 1.新建Canvas 此处要选择Overlay 否则排行榜会无法拖动 此处RankingBox默认状态为SetActive(false) bg:排行榜背景 也可以把背景让在

    2024年02月02日
    浏览(56)
  • Unity微信小游戏使用微信云开发记录

    最近项目上架微信小游戏,首先使用了微信官方sdk转成微信小游戏,官方地址如下: https://github.com/wechat-miniprogram/minigame-unity-webgl-transform 官方给了各种指导,虽然都有但是都不太精哈哈 因为要做排行榜,云存档,而我司没服务器,那只能用微信云开发了。具体开通啥的初始

    2023年04月09日
    浏览(54)
  • Unity微信小游戏资源下载失败问题

    unity导出微信小游戏后,打开报错 plugin.js:77 [PLUGIN ERROR 11:30.26.366] 下载资源包失败: networkType: wifi ; isVisible: true downloadFile:fail createDownloadTask:fail invalid url {}(env: Windows,mg,1.06.2210310; lib: 2.27.2) 这个问题是导出时没有填写游戏资源CDN 原来的版本没问题,升级之后出现的 游戏资源CD

    2024年02月09日
    浏览(86)
  • Unity微信小游戏登录授权获取用户信息

    最近需要在接微信获取用户信息的功能,在小游戏官方API中翻找资料。不得不说官方接口很多、很全,但是真的很乱而且部分遗漏。 对于不明所以的人来说,真的非常不友好。文档一堆堆的罗列下来,有些也不知道要怎么组合使用。 文档下有不少留言也是“骂骂咧咧”想必

    2024年02月02日
    浏览(59)
  • Unity-微信小游戏上架流程-个人开发者

    写在前面         微信上架流程个人认为比较繁琐,而且严格,时间跨度长。在微信平台上架小游戏,实际上相当于将一个Unity WebGL的工程上架到微信小程序,只不过将微信小程序的类型设置成小游戏,使用微信专门的打包工具打包导出,并且使用微信专门的调试工具进行

    2024年04月17日
    浏览(44)
  • unity开发微信小游戏3-获取微信权限

    ` 用unity3d开发微信小游戏,遇到了一些问题,记录一下, 同时创建了一个交流群QQ 641029627,有需要的可以加入一起讨论,广告哥远离 提示:以下是本篇文章正文内容,下面案例可供参考 首先SDK里面的微信小游戏-使用好友关系链要勾选 初始化SDK,首次调用 获取设置,也就是

    2023年04月09日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包