跳到主要内容

物理

PlayCanvas 的物理系统支持重力、碰撞、力和约束,由 ammo.js 驱动。

入门​

ammo.js 是 WASM 库,在 React 中按需加载,只有需要时才分发,可减小初始包。也可先渲染内容,再等待物理,或由交互触发加载,尽快显示场景。

先安装 sync-ammo:

npm install sync-ammo

再为根 Application 添加 usePhysics:

提示

仅设置 usePhysics 时才加载 ammo.js。

<Application usePhysics>
<Entity>
<Rigidbody type="box" />
</Entity>
</Application>

用法​

给实体添加 RigidBody 和 Collision 即参与模拟。下例创建静态地面、下落球体和盒体:

物理属性​

可调整刚体和碰撞属性,详情见物理文档。

<RigidBody
type="dynamic"
mass={1} // Object mass
linearDamping={0.1} // Air resistance for movement
angularDamping={0.1} // Air resistance for rotation
friction={0.5} // Surface friction
restitution={0.3} // Bounciness (0 = no bounce, 1 = perfect bounce)
/>
<Collision
type="box"
halfExtents={[1, 1, 1]} // Size for box collision
radius={0.5} // Radius for sphere/cylinder collision
height={2} // Height for capsule/cylinder collision
/>

usePhysics Hook​

物理引擎异步创建,可用 usePhysics 响应其状态。

import { usePhysics } from '@playcanvas/react/hooks';

const PhysicsStatus = () => {
const { isPhysicsEnabled, isPhysicsLoaded, physicsError } = usePhysics();
// ...
};

状态信息和接口详见 usePhysics。

更完整内容见物理手册。

故障排查​

webpack 提示无法解析 sync-ammo​

sync-ammo 是可选依赖,仅物理需要。未安装时,webpack,包括 next build --webpack,会因构建时解析全部导入而警告:

Module not found: Error: Can't resolve 'sync-ammo'

此警告不影响未启用物理的应用。React 仅在 usePhysics 开启时加载,Vite 和 Turbopack 不会因此警告。

webpack 中可忽略该模块以消除警告:

webpack.config.js
const webpack = require('webpack');

module.exports = {
// ...
plugins: [
new webpack.IgnorePlugin({ resourceRegExp: /^sync-ammo$/ })
]
};

Next.js 可添加到 next.config.mjs,但仅限 next build --webpack;默认 Turbopack 遇到 webpack 配置会失败:

next.config.mjs
export default {
webpack: (config, { webpack }) => {
config.plugins.push(new webpack.IgnorePlugin({ resourceRegExp: /^sync-ammo$/ }));
return config;
}
};
注意

IgnorePlugin 即使已安装也阻止打包 sync-ammo,启用物理时应移除。