-
Creator 版本: 3.6.0
-
目标平台:浏览器
-
重现方式:运行代码复现
-
首个报错:index.js:1 Error: Error: 以 file:///E:/coyouxi/NewProject_1/node_modules/wasm_mod/ 为起点找不到模块 “”
at rejector (system.js:1188:13)
at resolve (system.js:1219:9)
at systemJSPrototype.resolve (system.js:1241:10)
at system.js:336:39
at Array.map ()
at system.js:334:43 -
之前哪个版本是正常的:无
-
编辑器操作系统:windows 10
-
重现概率: 必然重现
我使用rust写了个rsa加密,使用wasm-pack build --target web生成了一个pkg,把pkg文件夹里的文件复制到wasm_mode文件夹里,放到cocos项目根目录,执行
npm install --save ./wasm_mod
我在cocos里面安装其他npm报
然后在ts程序里引用,我这样操作在react程序中运行的很好,但是在cocos里面报上面的错误,
我的引用方式为:
import init, { encrypt } from “wasm_mod”;
调用方式为:
init().then(res => {
let aa = encrypt(‘dd’);
console.log(aa);
});
具体js引用rust wasm可参考https://blog.csdn.net/weixin_47560078/article/details/130589024这篇文章,或者搜索相关,网上文章较多,有的是直接引用js,有的使用npm安装,我试了两种方式都行,我在react里面是用npm安装的,可以正常调用成功,但是在cocos中不行。
网上搜到有的方法是,不使用npm直接引用生成的包中的js文件,会报大概意思是不是标准的cjs模块的错误,项目要求使用wasm,已经探索3天,仍然没有解决。
也有这篇文章https://www.jianshu.com/p/1bc23892589c,但是只是演示的了简单的代码,这种方式如果rust文件中有import其他库,我的代码中引用了其他库,那么将报这篇文章https://blog.csdn.net/cucibala/article/details/114235063中的错误。
我是前端开发人员,但是因项目需求,要往cocos里面集成功能才接触cocos,请大家不吝赐教,多多指点。
建议wasm 文件还是放到资源目录下(assets), 然后用XMLHttpRequest 请求取得arraybuffer后再自己用胶水码实例,估计cc官方还未搞node_module路径下的wasm
具体怎么做有指引吗?已经用emscripten编好了.js和.wasm文件,放到了assets/rvo2目录。下一步具体怎么做呢?
你编译出来的js 看看ta是怎様加载wasm, 如果是url, 可以先用assetManager 加载 wasm文件, 取得nativeUrl, 传给 js那个加载api。 如果没有, 你看看有没有基于arraybuffer实例的, 应该是调用 WebAssembly.Instance的代码, 用XMLHttpRequest/fetch 加载arraybuffer, 或assetManager加载的是否为BufferAsset , 把arraybuffer 传到js 就可以了
把js和wasm文件放入assets\scripts\3rd\rvo2目录,打开编辑器就报错:
[Scene] failed to asynchronously prepare wasm: Error: ENOENT: no such file or directory, open ‘undefined\rvo2.wasm’
Error: [Scene] failed to asynchronously prepare wasm: Error: ENOENT: no such file or directory, open ‘undefined\rvo2.wasm’
at file:///G:/x1-dev/x1_proj_cli/client/temp/programming/packer-driver/targets/editor/chunks/5d/file:/G:/x1-dev/x1_proj_cli/client/assets/scripts/3rd/rvo2/rvo2.js:678:6
相关的rvo2.js代码:
function instantiateArrayBuffer(binaryFile, imports, receiver) {
return getBinaryPromise(binaryFile).then((binary) => {
return WebAssembly.instantiate(binary, imports);
}).then(receiver, (reason) => {
err(`failed to asynchronously prepare wasm: ${reason}`);
// Warn on some common problems.
if (isFileURI(wasmBinaryFile)) {
err(`warning: Loading from a file URI (${wasmBinaryFile}) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing`);
}
abort(reason);
});
}
那不正常吗, js 默认是相对路径的wasm, cc 做了路由, 所以肯定不能直接取, 你消化一下我説的, 你js是肯定要改的
步骤概述
-
编译 RVO2 库为 WASM:
使用 Emscripten 编译 RVO2 库的 C++ 代码为 WASM,生成rvo2.js和rvo2.wasm文件。emcc Agent.cpp KdTree.cpp Obstacle.cpp RVOSimulator.cpp binds.cpp -I. -o rvo2.js -s WASM=1 -s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" --bind -s MODULARIZE=1 -s EXPORT_ES6=1 -
拷贝生成的文件到项目目录:
将rvo2.js和rvo2.wasm文件拷贝到 Cocos Creator 项目的assets/scripts/3rd/rvo2/目录下。 -
修改
rvo2.js中的scriptDirectory:
在rvo2.js文件中修改scriptDirectory变量和locateFile函数,以确保 WASM 文件能够被正确加载。var scriptDirectory = '../../scripts/3rd/rvo2/'; function locateFile(path) { if (Module['locateFile']) { return Module['locateFile'](path, scriptDirectory); } return scriptDirectory + path; } -
创建 TypeScript 声明文件:
在assets/scripts/3rd/rvo2/目录下创建rvo2.d.ts文件,提供模块的 TypeScript 声明。declare module 'assets/scripts/3rd/rvo2/rvo2' { const RVO2Module: () => Promise<any>; export default RVO2Module; } -
在
Splash.ts中使用 RVO2 模块:
在Splash.ts文件中导入并使用 RVO2 模块。import RVO2Module from 'assets/scripts/3rd/rvo2/rvo2'; RVO2Module().then((instance: any) => { console.log("=== rvo2 =========== ", instance); });
遇到的问题
当尝试在 Cocos Creator 中运行项目时,遇到了一个错误,指出附加到 “Splash” 的脚本 “8bcfek46dtC07oHYPIB8vbb” 缺失或无效。错误信息如下:
Node path: "Splash"
Script UUID: "8bcfe938-e9db-42d3-ba07-60f201f2f6db"
Class ID: "8bcfek46dtC07oHYPIB8vbb"
Error: [Scene] Script "8bcfek46dtC07oHYPIB8vbb" attached to "Splash" is missing or invalid.
我是新手,应该有什么基础问题没搞对。
这不就是 你splash.ts 编译没过, 有报错才出现script missing
去掉相关的代码是可以编过的
import RVO2Module from ‘assets/scripts/3rd/rvo2/rvo2’;
RVO2Module().then((instance: any) => {
console.log("=== rvo2 =========== ", instance);
});
另外,cocos版本是3.8.1