You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在@react-three/cannon中创建物理行为符合预期的二十面体d20骰子

问题原因

  1. useConvexPolyhedron 依赖手动传入碰撞体的顶点数组、面索引数组两个核心参数,你没有将实例化的二十面体几何体的对应参数传入Hook,导致物理碰撞体没有正确生成,所以出现穿模问题。
  2. 代码中存在尺寸不匹配问题:你实例化了半径为4的二十面体几何体,但实际渲染用的几何体参数是半径1,物理碰撞体和渲染体尺寸不一致会导致后续碰撞效果错位。
  3. 物理Hook内定义的position和mesh上定义的position冲突,以物理Hook的配置为准即可。

修复后的代码

const IcosahedronDice = (props) => {
  // 渲染用和物理计算用保持相同的几何参数:半径1,细分0
  const icosaGeo = new THREE.IcosahedronGeometry(1, 0);
  // 提取顶点数组,转成cannon需要的格式
  const vertices = Array.from(icosaGeo.attributes.position.array);
  // 提取面索引数组,按3个一组拆分对应每个三角面
  const indices = Array.from(icosaGeo.index.array);
  const faces = [];
  for (let i = 0; i < indices.length; i += 3) {
    faces.push([indices[i], indices[i + 1], indices[i + 2]]);
  }

  // 替换useBox为useConvexPolyhedron,传入vertices和faces参数
  const [ref] = useConvexPolyhedron(() => ({
    mass: 1,
    position: [0, 10, 0],
    args: [vertices, faces]
  }));

  return (
    <mesh ref={ref} castShadow receiveShadow>
      <icosahedronBufferGeometry attach="geometry" args={[1, 0]}/>
      <meshStandardMaterial attach="material" color="#802d2d" />
    </mesh>
  )
}

额外注意

如果滚动时仍有异常,可以给Physics组件添加iterations={10}参数提高物理计算精度,避免小面碰撞检测遗漏。

内容的提问来源于stack exchange,提问作者Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 20:15:07