babylon.js+vite使用Havok物理引擎遇到的问题

Babylon.js 8.0之后将Havok作为官方推荐的物理引擎(Havok被微软收购),官方文档中Features>Deep Dive>Physics也给出了非常多的示例代码可供参考。按理说应该很容易上手的,可是偏偏我就卡在了第一步,连基本的物理引擎环境都准备不好。最后发现竟然和vite构建工具有关,这里记录下错误信息以及解决办法,也许可以帮助到遇到同样问题的朋友。

首先执行如下命令安装havok

npm install @babylonjs/havok

接下来导入HavokPhysics并实例化,示例仅给出相关代码,其他代码均未展示

import HavokPhysics from "@babylonjs/havok"

// 需要在异步函数中执行
async init() {
  const HK = await HavokPhysics()
}

浏览器控制台监控发现await HavokPhysics()这句代码会导致下面的报错信息,因为Havok web使用了Webassembly,这个错误表示havok没有正确处理wasm文件,但是检查wasm文件在havok/lib/esm目录下是存在的,具体为什么报错就不知道了。

Uncaught (in promise) RuntimeError: Aborted(CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 64 6f @+0). Build with -sASSERTIONS for more info.
    at abort (@babylonjs_havok.js?v=5e7cbcf8:286:15)
    at @babylonjs_havok.js?v=5e7cbcf8:355:11

经过一番搜索和测试发现这个跟vite的行为有关系,而刚好我的项目就是使用vite构建的。vite在开发环境会对node_modules中的第三方库进行预构建处理,主要目的是将CommonJS转为ES模块避免浏览器无法直接识别,以及合并一些零散的依赖文件,这些预构建处理可能破坏了havok wasm文件的结构,导致实例化时编译报错。

解决的办法就是创建vite.config.ts文件(如果已经创建则添加相应配置项即可),在其中添加如下optimizeDeps配置,目的是告诉vite不要针对havok进行预构建处理,这样havok引擎就能正常工作了。

import { defineConfig } from 'vite'
export default defineConfig({
  // 排除预优化havok,否则会导致编译失败,新增配置项需要重启server
  optimizeDeps: {
    exclude: ["@babylonjs/havok"],
  },
})

如果你需要Babylon.js+vite+typescript并使用了havok物理引擎的完整项目模板可以参考"
https://github.com/eldinor/bp800/blob/main/vite.config.ts"

原文链接:,转发请注明来源!