2025-01-07 Unity 使用 Tip3 —— 游戏保存数据到 Application.persistentDataPath 不生效解决方案更新
文章目录
- 1 问题描述
- 2 老版解决方案(测试可行)
- 2.1 创建 js 脚本
- 2.2 添加 js 引用
- 3 新版解决方案(测试不可行)
- 4 实际问题
WebGL 平台限制了文件访问系统,在 Unity 以前版本中,开发者想要在 WebGL 上保存游戏到本地很不方便。
目前,Unity 新版中给出了一项解决方案,但经测试,该方案目前不可取(截止 2025-01-07)。
- Unity 版本:6000.0.26f1c1
1 问题描述
Unity WebGL 平台中,游戏保存数据到 Application.persistentDataPath 不生效(官方链接:https://docs.unity3d.com/ScriptReference/Application-persistentDataPath.html)。

老版本 Unity 2019.2 官方给出了解释:Unity WebGL 将会话之间必须保留的所有文件(例如 PlayerPrefs 或保存在 persistentDataPath 中的文件)存储到浏览器 IndexedDB。这是一个异步 API,因此不确定何时完成。

2 老版解决方案(测试可行)
借助 js 脚本,在保存后显式写入数据到/idbfs中。
2.1 创建 js 脚本
在项目 /Assets/Plugins/ 目录下创建名为 Save 的 txt 文件,写入如下内容,更改后缀名为 .jslib:
mergeInto(LibraryManager.library, {// 刷新数据到 IndexedDBSyncDB: function () {FS.syncfs(false, function (err) {if (err) console.log("syncfs error: " + err);});}
});
2.2 添加 js 引用
- 在需要使用 js 脚本的 C# 代码块中添加命名空间
System.Runtime.InteropServices;
引用。 - 在需要使用 js 脚本的 C# 代码块中加入外部函数声明。
- 在负责保存的 C# 代码后面加入外部函数调用。
示例:
// 1. 引用命名空间
#if UNITY_WEBGL && !UNITY_EDITOR
using System.Runtime.InteropServices;
#endifpublic class TxtHelper
{// 2. 加入外部函数声明
#if UNITY_WEBGL && !UNITY_EDITOR[DllImport("__Internal")]private static extern void SyncDB();
#endifpublic static void Save(string filePath, string content){... // Your code here// 3. 调用外部函数
#if UNITY_WEBGL && !UNITY_EDITORSyncDB();
#endif}public static string Load(string filePath){...}
}
参考链接:
- https://blog.csdn.net/mkr67n/article/details/127348730。
- https://blog.csdn.net/xiaotaiyang_gege/article/details/135862196。
3 新版解决方案(测试不可行)
对于较新的 Unity 版本(2021.3.44f1、2022.3.44f1、6000.0.11f1 及以上),有此问题的更新:
- 修复了 Application.persistentDataPath 不会自动持久化的问题,通过添加新的 JS 配置选项“autoSyncPersistentDataPath: true”来启用 Application.persistentDataPath 到 IndexedDB 的自动同步。
- 该选项位于 Builds/Index.html 文件中,取消注释并刷新正在运行的构建页面,问题将得到解决。
即,不需要任何代码操作,只需要打包完成后,将 Builds/Index.html 文件中的第 78 行取消注释即可。

当然,前提是你选择了 WebGL 平台的 Default 模板,如下图所示(其他模板自行探索)。

如果不想每次打包后都修改 Builds/Index.html 文件,也可以直接修改模板中的 Index.html ,一劳永逸。其位置在 S:\Unity Editor\6000.0.26f1c1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\WebGLTemplates\Default 目录中。

参考链接:
- https://issuetracker.unity3d.com/issues/webgl-streamwriter-not-triggering-syncfs-when-writing-a-file-to-slash-idbfs。
- https://gamedev.stackexchange.com/questions/184369/file-saved-to-indexeddb-lost-unless-we-change-scenes。
4 实际问题
在 Unity 6000.0.26f1c1 版本中,按照步骤将上述第 78 行代码注释后,打包运行时出现如下报错:


报错信息:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘length’)
at Object.hashName (WebGL.framework.js:9:66347)
at Object.lookupNode (WebGL.framework.js:9:66977)
at Object.rmdir (WebGL.framework.js:9:54898)
at Object.rmdir (WebGL.framework.js:9:2685)
at Object.rmdir (WebGL.framework.js:9:75286)
at ___syscall_rmdir (WebGL.framework.js:9:177933)
at WebGL.wasm:0x14b27f
at WebGL.wasm:0x2610db6
at WebGL.wasm:0x26167f1
at WebGL.wasm:0x30ac93e
at WebGL.wasm:0x30ad59b
at WebGL.wasm:0x26101ae
at WebGL.wasm:0x29c020e
at WebGL.wasm:0x29bca03
at WebGL.wasm:0x29c119d
at WebGL.wasm:0x29c11b3
at WebGL.wasm:0x29b9849
at WebGL.wasm:0x29b6b88
at WebGL.wasm:0x327a445
at WebGL.framework.js:9:142371
at HandleError (WebGL.framework.js:9:142414)
at WebGL.framework.js:9:144075
解决方法是:将 config.autoSyncPersistentDataPath 设置为 false 或将该行注释掉。问题跟踪来源:https://issuetracker.unity3d.com/issues/webgl-typeerror-cannot-read-properties-of-undefined-reading-length-error-is-thrown-when-starting-the-player-when-config-dot-autosyncpersistentdatapath-is-set-to-true。

也就是说,新版解决方案在 Unity 6000.0.26f1c1 版本中失效。
目前退回到使用老版解决方案,测试可行。
WebGL 可真是太好玩辣!
相关文章:
2025-01-07 Unity 使用 Tip3 —— 游戏保存数据到 Application.persistentDataPath 不生效解决方案更新
文章目录 1 问题描述2 老版解决方案(测试可行)2.1 创建 js 脚本2.2 添加 js 引用 3 新版解决方案(测试不可行)4 实际问题 WebGL 平台限制了文件访问系统,在 Unity 以前版本中,开发者想要在 WebGL 上保存…...
关于重构一点简单想法
关于重构一点简单想法 当前工作的组内,由于业务开启的时间正好处于集团php-》go技术栈全面迁移的时间点,组内语言技术栈存在:php、go两套。 因此需求开发过程中通常要考虑两套技术栈的逻辑,一些基础的逻辑也没有办法复用。 在这…...
使用 `llama_index` 构建智能问答系统:多种文档切片方法的评估
使用 llama_index 构建智能问答系统:多种文档切片方法的评估 代码优化与解析1. **代码结构优化**2. **日志管理**3. **环境变量管理**4. **模型初始化**5. **提示模板更新**6. **问答函数优化**7. **索引构建与查询引擎**8. **节点解析器测试** 总结 在现代自然语言…...
Vue3 内置组件之KeepAlive
文章目录 Vue3 内置组件之KeepAlive概述用法简单使用include & excludemax Vue3 内置组件之KeepAlive 概述 <KeepAlive> 是一个内置组件,它的功能是在多个组件间动态切换时缓存被移除的组件实例。 组件在加载时会经历初始、挂载、更新、销毁生命周期&a…...
生物医学信号处理--绪论
前言 参考书籍:刘海龙,生物医学信号处理,化学工业出版社 生物医学信号分类 1、由生理过程自发或者诱发产生的电生理信号和非电生理信号 • 电生理信号:ECG/心电、EEG/脑电、EMG/肌电、 EGG/胃电、 EOG/眼电 • 非电生理信号&am…...
30天开发操作系统 第 12 天 -- 定时器
前言 定时器(Timer)对于操作系统非常重要。它在原理上却很简单,只是每隔一段时间(比如0.01秒)就发送一个中断信号给CPU。幸亏有了定时器,CPU才不用辛苦地去计量时间。……如果没有定时器会怎么样呢?让我们想象一下吧。 假如CPU看不到定时器而仍想计量时…...
android 启动页倒计时页面编写
一、需求和技术 1、实现5,4,3,2,1启动页倒计时 2、倒计时实现使用CountDownTimer 二、activity代码 public class OpenActivity extends AppCompatActivity {private Button in;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanc…...
Win10和11 git/Android Studio遇到filename too long问题的解决
1、打开windows长文件、长路径支持: 可以参考这篇文章: 修改注册表方法: 使用Admin登陆machine,在run中输入regedit并回车; 找到路径 ’Computer -> HKEY_LOCAL_MACHINE -> SYSTEM -> CurrentControlSet -&g…...
OpenCV相机标定与3D重建(43)用于计算矫正和重映射的变换函数initUndistortRectifyMap()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 计算畸变矫正和校正变换映射。 该函数计算联合的畸变矫正和校正变换,并以 remap 所需的地图形式表示结果。矫正后的图像看起来像是原…...
运行npm install 时,卡在sill idealTree buildDeps没有反应
运行npm install 时,卡在sill idealTree buildDeps没有反应 原因: 淘宝镜像源的域名早已经过期,所以我们需要绑定新的镜像源。 2021 年,淘宝就发布了消息称,npm 淘宝镜像已经从 registry.npm.taobao.org 切换到了 re…...
与 Oracle Dataguard 相关的进程及作用分析
与 Oracle Dataguard 相关的进程及作用分析 目录 与 Oracle Dataguard 相关的进程及作用分析与 Oracle Dataguard 相关的进程及作用分析一、主库的进程1、LGWR 进程2、ARCH进程3、LNS 进程 二、备库的进程1、RFS 进程2、ARCH3、MRP(Managed Recovery Process&#x…...
如何在Windows上编译OpenCV4.7.0
前言 参考:Win10 下编译 OpenCV 4.7.0详细全过程,包含xfeatures2d 这里在其基础上还出现了一些问题,仅供参考。 正文 一、环境 1、win10 2、cmake-gui 3、opencv4.7.0 4、VS2019 二、编译过程 1、下载需要的文件: 通…...
get和post有什么区别
GET和POST是HTTP协议中两种常用的请求方法,它们在用途、参数传递方式、缓存处理、安全性等方面存在显著差异。 以下是对GET和POST区别的详细讲解,并给出示例演示。 一、GET和POST的区别 用途 GET:主要用于获取信息,即进行查询操…...
STM32之CAN通讯(十一)
STM32F407 系列文章 - CAN通讯(十一) 目录 前言 一、CAN 二、CAN驱动电路 三、CAN软件设计 1.CAN状态初始化 2.头文件相关定义 3.接收中断服务函数 4.用户层使用 1.用户层相关定义 2.发送数据 3.接收数据 1.查询方式处理 2.中断方式处理 3…...
23.行号没有了怎么办 滚动条没有了怎么办 C#例子
新建了一个C#项目,发现行号没有了。 想把行号调出来,打开项目,选择工具>选项> 如下图,在文本编辑器的C#里有一个行号,打开就可以了 滚动条在这里:...
QT 下拉菜单设置参数 起始端口/结束端口/线程数量 端口扫描4
上篇文章QT实现 端口扫描暂停和继续功能 3-CSDN博客 双击 添加对话框类 界面设计 由于主体代码已经写完,只需要更改参数的获取即可 获取起始端口结束端口的输入 槽函数 给主界面类添加调用对话框类的功能 实现功能:点击菜单项可以弹出对话框窗体 增加槽…...
spark——RDD算子集合
目录 算子转换算子示例mapflatMapReduceByKeyfilterdistinctglomgroupBygroupByKeySortBysortByKeyunion交集intersection和差集subtractjoinpartitionBymapPartitionsample 行动算子示例ForeachPartitionForeachSaveAsTextFileCountByKeyReducefoldfirst、take、counttop、tak…...
【ArcGIS Pro二次开发实例教程】(1):图层的前置、后置
一、简介 此工具要实现的功能是:将内容框中当前选定的图层移到最顶层或最底层。 主要技术要点包括: 1、Config.daml文件设置(UI设置) 2、按钮的图片和位置设置 3、当前选定图层的获取 4、图层在内容列表中位置的获取和移动 …...
idea 运行 docker-compose 文件问题
我idea 连接远程docker 然后本地运行compose 文件出了问题 C:\Program Files\Docker\Docker\resources\bin\docker.exe compose -f D:\aproject\group-buy-market\suger_group_buy\docs\dev-ops\docker-compose-environment.yml -p dev-ops up -d正在准备 Docker SSH 环境…ti…...
深度学习中的正则化方法
最近看到了正则化的内容,发现自己对正则化的理解已经忘得差不多了,这里在整理一下,方便以后查阅。 深度学习中的正则化方法 1. L2 正则化(L2 Regularization)2. L1 正则化(L1 Regularization)3.…...
LInux单机安装Redis
1. 安装gee工具包 由于Redis是基于c语言编写的所以安装的时候需要先安装gee以及gcc的依赖,yum云用不了可以看一下这个 linux 替换yum源镜像_更换yum镜像源-CSDN博客 yum install -y gcc tcl 2. 添加redis的压缩包 3. 上传到Linux 上传到 /usr/local/src 目录、这个目录一般用于…...
kafka使用以及基于zookeeper集群搭建集群环境
一、环境介绍 zookeeper下载地址:https://zookeeper.apache.org/releases.html kafka下载地址:https://kafka.apache.org/downloads 192.168.142.129 apache-zookeeper-3.8.4-bin.tar.gz kafka_2.13-3.6.0.tgz 192.168.142.130 apache-zookee…...
深入理解 pytest_runtest_makereport:如何在 pytest 中自定义测试报告
pytest_runtest_makereport 是 pytest 系统中的一个钩子函数,它允许我们在测试执行时获取测试的报告信息。通过这个钩子,我们可以在测试运行时(无论是成功、失败还是跳过)对测试结果进一步处理,比如记录日志、添加自定…...
嵌入式技术之Linux(Ubuntu) 一
一、Linux入门 1.硬件和操作系统以及用户的关系 一个传感器,获得数据后,需要向服务器发送数据。传感器传数据给上位机。 上位机需要一个程序来接收数据,那么这个上位机是什么机器? 我们的笔记本电脑就可以当成上位机。 两个手…...
VB.NET CRC32 校验
在 VB.NET 中实现 CRC32 校验并在校验失败时退出程序,你可以按照以下步骤进行: 实现 CRC32 计算函数:首先,你需要一个函数来计算给定数据的 CRC32 值。 比较计算的 CRC32 值:然后,你需要将计算出的…...
iOS - 弱引用表(Weak Reference Table)
1. 基本数据结构 // 弱引用表的基本结构 struct weak_table_t {weak_entry_t *weak_entries; // 保存所有的弱引用对象size_t num_entries; // 当前存储的弱引用数量uintptr_t mask; // 哈希表大小掩码uintptr_t max_hash_displacement; /…...
Taro地图组件和小程序定位
在 Taro 中使用腾讯地图 1.首先在项目配置文件 project.config.json 中添加权限: {"permission": {"scope.userLocation": {"desc": "你的位置信息将用于小程序位置接口的效果展示"}} }2.在 app.config.ts 中配置&#x…...
汇编实现函数调用
x86_64 通过将函数参数存放在栈中的方式来实现参数传递。 # PURPOSE: Program to illustrate how functions work # This program will compute the value of # 2^3 5^2 ## Everything in the main program is stored in registers, # so the data section…...
C#—Task异步的常用方法及TaskFactory工厂类详解
Task异步的常用方法 C# 中的 Task 类是 System.Threading.Tasks 命名空间的一部分,用于表示异步操作。 以下是一些常用的 Task 类方法: 一、Task.Run(Action action): 此静态方法用于在后台运行一个新任务,并返回与该任务关联的 Task 实例…...
JAVA | 通过自定义注解与AOP防止接口重复提交
关注:CodingTechWork 引言 在Web应用开发中,特别是在处理表单提交或API调用时,可能会遇到用户因网络延迟、按钮多次点击等原因导致的重复提交问题。为了解决这一问题,通常的做法是在前端禁用提交按钮,或者在后端使用唯…...
从零手写实现redis(四)添加监听器
1、删除监听器 /*** 删除监听器接口** author binbin.hou* since 0.0.6* param <K> key* param <V> value*/ public interface ICacheRemoveListener<K,V> {/*** 监听* param context 上下文* since 0.0.6*/void listen(final ICacheRemoveListenerContext&…...
Spring Boot项目中使用单一动态SQL方法可能带来的问题
1. 查询计划缓存的影响 深入分析 数据库系统通常会对常量SQL语句进行编译并缓存其执行计划以提高性能。对于动态生成的SQL语句,由于每次构建的SQL字符串可能不同,这会导致查询计划无法被有效利用,从而需要重新解析、优化和编译,…...
51单片机——中断(重点)
学习51单片机的重点及难点主要有中断、定时器、串口等内容,这部分内容一定要认真掌握,这部分没有学好就不能说学会了51单片机 1、中断系统 1.1 概念 中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的,中断功能的存在&#…...
MySQL insert or update方式性能比较
MySQL中,有如下两种方式,哪种方式比较好? 1、先使用enterprise_id字段查询数据表,如果表中存在记录,则更新记录;如果不存在,则插入记录; 2、使用“INSERT INTO XXX ON DUPLICATE K…...
Linux下常用命令
本文以笔记的形式记录Linux下常用命令。 注1:限于研究水平,阐述难免不当,欢迎批评指正。 注2:文章内容会不定期更新。 一、Ubuntu 添加账号 useradd -m -s /bin/bash -d /home/newuser newuser:newuser passwd newuser 二、 Ce…...
计算机网络、嵌入式等常见问题简答
1.嵌入式系统中经常要用到无限循环,如何用C编写死循环 答:while(1){}或者for(;;) 2.程序的局部变量存在于哪里,全局变量存在于哪里,动态申请数据存在于哪里。 答:程序的局部变量存在于栈区;全局变量存在…...
嵌入式中QT实现文本与线程控制方法
第一:利用QT进行文件读写实现 利用QT进行读写文本的时候进行读写,读取MP3歌词的文本,对这个文件进行读写操作。 实例代码,利用Qfile,对文件进行读写。 //读取对应文件文件,头文件的实现。 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #incl…...
141.环形链表 142.环形链表II
141.环形链表 & 142.环形链表II 141.环形链表 思路:快慢指针 or 哈希表 快慢指针代码: class Solution { public:bool hasCycle(ListNode *head) {if(headnullptr||head->nextnullptr)return false;ListNode *fasthead->next; //不能设置成…...
计算机网络掩码、最小地址、最大地址计算、IP地址个数
一、必备知识 1.无分类地址IPV4地址网络前缀主机号 2.每个IPV4地址由32位二进制数组成 3. /15这个地址表示网络前缀有15位,那么主机号32-1517位。 4.IP地址的个数:2**n (n表示主机号的位数) 5.可用(可分配)IP地址个数&#x…...
第3章——HTTP报文内的HTTP信息
第3章——HTTP报文内的HTTP信息 HTTP报文 用于HTTP协议交互的信息被称为HTTP报文,分为请求报文和响应报文。分为Head,Body 结构: 请求行:包含用于请求的方法,请求URI和HTTP版本。 状态行:包含表明响应…...
Minio-Linux-安装
文章目录 1.Linux安装1.下载源码包2.上传到/usr/local/minio1.进入目录2.上传 3.开放执行权限4.创建minio文件存储目录及日志目录5.编写启动的shell脚本1.脚本编写2.赋予执行权限 6.启动!1.执行run脚本2.查看日志3.开放9001和9000端口1.服务器2.安全组3.访问&#x…...
面试高阶问题:对称加密与非对称加密的原理及其应用场景
目录 第一章 对称加密原理及算法实现 第二章 非对称加密原理及算法实现 第三章 对称加密与非对称加密的应用场景 第四章 对称加密与非对称加密的应用实例 第五章 对称加密与非对称加密的对比分析 第一章 对称加密原理及算法实现 1.1 对称加密的原理 对称加密,又称私钥加密…...
报错 - decord 在 macOS Silicon 安装失败
问题:在 macOS M2 上 pip 安装 decord 出错: ERROR: Could not find a version that satisfies the requirement decord (from versions: none) ERROR: No matching distribution found for decord使用 decord 源码编译,make 也会出很多问题 …...
英伟达 RTX 5090 显卡赋能医疗大模型:变革、挑战与展望
一、英伟达 RTX 5090 与 RTX 4090 技术参数对比 1.1 核心架构与制程工艺 在探讨英伟达 RTX 4090 与 RTX 5090 的差异时,核心架构与制程工艺无疑是最为关键的基础要素,它们从根本上决定了两款显卡的性能上限与应用潜力。 1.1.1 核心架构差异 RTX 4090…...
PyCharm简单调试
本文简单讲述一下PyCharm中经常用到的调试操作。 示例代码如下: for i in range(10):print("hello", i)if i > 2:print("ok!")在代码前面打上断点,如下图所示: 单机调试按钮Debug 单机Resume Program按钮…...
快速入门Spring Cloud Alibaba,轻松玩转微服务
1 快速入门Spring Cloud Alibaba,轻松玩转微服务 1.1 架构 架构图: 1.2 项目结构 1.2.1 系统框架版本 版本适配查看:https://sca.aliyun.com/docs/2023/overview/version-explain/ Spring Boot Version :3.2.4 Spring Clo…...
浅尝Appium自动化框架
浅尝Appium自动化框架 Appium自动化框架介绍Appium原理Appium使用安装平台驱动 Appium自动化框架介绍 Appium 是一个开源的自动化测试框架,最初设计用于移动应用的测试,但现在它也扩展了对桌面端应用的支持。Appium 使得自动化测试变得更加简单…...
poi-tl+kkviewfile实现生成pdf业务报告
需求背景,需要把ai生成的一些业务数据,生成一份pdf报告 需求分析 简单来说,就是json生成pdf的方案。 直接生成pdf。适合一些pdf样式简单的场景,一般就是纯文本按序渲染,或者是纯表格。如果需要一些复杂的排布&#x…...
python导入模块失败
运行下面代码模块,出现报错,导入模块失败 import torch from layers.Embed import DataEmbedding from layers.Conv_Blocks import Inception_Block_V1 将你自己的目录添加到 sys.path,假设你的目录位置是D://winhzq//桌面//pydemo//…...
Vulkan 学习(12)---- Vulkan pipeline 创建
目录 Vulkan 渲染管线顶点输入阶段输入装配阶段顶点着色器阶段细分控制、评估着色器阶段(可选)几何着色器阶段(可选)图元装配阶段光栅化阶段片段着色器片段测试阶段混合阶段 Vulkan 渲染管线 渲染管线可以看作是一条生产流水线,定义了从输入顶点到输出图像的所有步…...