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)。

image-20250107001802329

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

image-20250107010458838

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 引用

  1. 在需要使用 js 脚本的 C# 代码块中添加命名空间 System.Runtime.InteropServices; 引用。
  2. 在需要使用 js 脚本的 C# 代码块中加入外部函数声明。
  3. 在负责保存的 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 行取消注释即可。

image-20250107012115743

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

image-20250107012433437

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

image-20250107012617172

​ 参考链接:

  • 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 行代码注释后,打包运行时出现如下报错:

image-20250107032152086 image-20250107032223093

报错信息:

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。

image-20250107033431171

​ 也就是说,新版解决方案在 Unity 6000.0.26f1c1 版本中失效。

​ 目前退回到使用老版解决方案,测试可行。

​ WebGL 可真是太好玩辣!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/66453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA的常用设置

目录 一、显示顶部工具栏 二、设置编辑区字体按住鼠标滚轮变大变小(看需要设置) 三、设置自动导包和优化导入的包(有的时候还是需要手动导包) 四、设置导入同一个包下的类,超过指定个数的时候,合并为*&a…

Anthropic 的人工智能 Claude 表现优于 ChatGPT

在人工智能领域,竞争一直激烈,尤其是在自然语言处理(NLP)技术的发展中,多个公司都在争夺市场的主导地位。OpenAI的ChatGPT和Anthropic的Claude是目前最具影响力的两款对话型AI产品,它们都能够理解并生成自然…

锂电池剩余寿命预测 | 基于BiLSTM-Attention的锂电池剩余寿命预测,附锂电池最新文章汇集

锂电池剩余寿命预测 | 基于BiLSTM-Attention的锂电池剩余寿命预测,附锂电池最新文章汇集 目录 锂电池剩余寿命预测 | 基于BiLSTM-Attention的锂电池剩余寿命预测,附锂电池最新文章汇集预测效果基本描述程序设计参考资料 预测效果 基本描述 锂电池剩余寿…

代码随想录算法训练营第四十天 | 股票问题

LeetCode 121.买卖股票的最佳时机&#xff1a; 文章链接 题目链接&#xff1a;121.买卖股票的最佳时机 思路 方法1&#xff1a;暴力 看到题目最直接的想法是双层遍历求最大区间差 class Solution:def maxProfit(self, prices):if len(prices) < 1:return 0result 0for…

秋叶大神中文版Stable Diffusion下载安装使用教程

Stable Diffusion是什么&#xff1f; StableDiffusion是一款开源的AI绘画软件&#xff0c;于2022年发布&#xff0c;由CompVis、StabilityAI和LAION的研究人员创建。该软件具有出色的图像生成功能&#xff0c;使用户能够从头开始绘制作品&#xff0c;也可以使用现有的图像进行…

1. 使用springboot做一个音乐播放器软件项目【前期规划】

背景&#xff1a; 现在大部分音乐软件都是要冲会员才可以无限常听的。对于喜欢听音乐的小伙伴&#xff0c;资金又比较紧张&#xff0c;是那么的不友好。作为程序员的我&#xff0c;也是喜欢听着歌&#xff0c;敲着代码。 最近就想做一个音乐播放器的软件&#xff0c;在内网中使…

景区民宿预约系统设计与实现(代码+数据库+LW)

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装景区民宿预约系统软件来发挥其高效地信息处理的作用&#…

【项目实战1】五子棋游戏

目录 C语言编程实现五子棋&#xff1a;&#xff1a; game.h game.c 1.打印菜单 2.打印棋盘 3.玩家下棋 4.判断五子连珠 5.判断输赢 6.游戏运行 game.c完整源代码展示 test.c C语言编程实现五子棋&#xff1a;&#xff1a; game.h #pragma once #include<stdio.h> …

【学习路线】Python 算法(人工智能)详细知识点学习路径(附学习资源)

学习本路线内容之前&#xff0c;请先学习Python的基础知识 其他路线&#xff1a; Python基础 >> Python进阶 >> Python爬虫 >> Python数据分析&#xff08;数据科学&#xff09; >> Python 算法&#xff08;人工智能&#xff09; >> Pyth…

游戏引擎学习第77天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾昨天的 bug 今天我们继续开发进度&#xff0c;进行调试昨天代码的问题&#xff0c;主要是关于如何跟踪玩家和敌人在世界中的高度位置。虽然我们做的是一款 2D 游戏&#xff0c;但我们希望能够处理多层的房间&#xff0c;玩家…

第30天:Web开发-PHP应用组件框架前端模版渲染三方插件富文本编辑器CVE审计

#知识点 1、安全开发-原生PHP-开发组件集合 2、安全开发-原生PHP-模版引擎渲染 3、安全开发-原生PHP-第三方编辑器 组件/框架 说明 [Web框架] Laravel 现代化、功能全面的框架&#xff0c;适合大多数Web应用。 Symfony 高度模块化、功能强大的框架&#xff0c;适合复杂…

with as提高sql的执行效率

实战sql with cte(UNIT_ID, UNIT_NAME, PARENT_UNIT_ID, UNIT_CODE ) as (select UNIT_ID, UNIT_NAME, PARENT_UNIT_ID , UNIT_CODEfrom HPFM_UNITunion allselect t.UNIT_ID, t.UNIT_NAME, t.PARENT_UNIT_ID, t.UNIT_CODEfrom HPFM_UNIT tjoin cte on t.PARENT_UNIT_ID cte.U…

计算机网络 (29)网络地址转换NAT

前言 网络地址转换&#xff08;Network Address Translation&#xff0c;NAT&#xff09;是计算机网络中的一种重要协议&#xff0c;它主要用于将私有IP地址转换为公共IP地址&#xff0c;以实现内部网络与外部网络之间的通信。 一、基本概念 NAT是一种在局域网&#xff08;LAN&…

Docker--Docker Volume(存储卷)

什么是存储卷&#xff1f; Docker的存储卷是一种将宿主机的本地文件系统中的某个目录与容器内部的文件系统中的某个目录建立绑定关系的机制。这种绑定关系意味着&#xff0c;当在容器的这个目录下写入数据时&#xff0c;会同步到宿主机的这个目录中&#xff1b;同样&#xff0…

STM32裸机开发转FreeRTOS教程

目录 1. 简介2. RTOS设置&#xff08;1&#xff09;分配内存&#xff08;2&#xff09;查看任务剩余空间&#xff08;3&#xff09;使用osDelay 3. 队列的使用&#xff08;1&#xff09;创建队列&#xff08;1&#xff09;直接传值和指针传值&#xff08;2&#xff09;发送/接收…

用豆包MarsCode IDE打造精美数据大屏:从零开始的指南

原标题&#xff1a;用豆包MarsCode IDE&#xff0c;从0到1画出精美数据大屏&#xff01; 豆包MarsCode IDE 是一个云端 AI IDE 平台&#xff0c;通过内置的 AI 编程助手&#xff0c;开箱即用的开发环境&#xff0c;可以帮助开发者更专注于各类项目的开发。 作为一名前端开发工…

PCB原理图的编译设置

设置步骤&#xff1a; 进入-->Project Options...&#xff0c;对照设置“致命错误”部分来设置即可

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 目录、这个目录一般用于…

黄仁勋演讲总结(2种显卡,1个开源大模型,1个数据采集平台)

研发算力显卡RTX50系列&#xff0c;PC端显卡GB10&#xff0c;开源大模型Cosmos&#xff08;用于机器人和自动驾驶&#xff09;&#xff0c; Isaac GR00T&#xff08;人形机器人的数据采集平台&#xff09;。 新一代 RTX 50 系列显卡 RTX 50 系列 GPU&#xff0c;相对之前系列&a…

初学Linux电源管理

学习文档出处&#xff1a; 万字整理 | 深入理解Linux电源管理&#xff1a;万字整理 | 深入理解Linux电源管理-CSDN博客 电源管理 因为设备需要用电&#xff0c;而且设备中的各个硬件所需要的电压是不一样的。故计算机需要对硬件的电源状态管理。但是电能并不是免费的&#x…