如何在@react-three/cannon中创建物理行为符合预期的二十面体d20骰子
问题原因
useConvexPolyhedron依赖手动传入碰撞体的顶点数组、面索引数组两个核心参数,你没有将实例化的二十面体几何体的对应参数传入Hook,导致物理碰撞体没有正确生成,所以出现穿模问题。- 代码中存在尺寸不匹配问题:你实例化了半径为4的二十面体几何体,但实际渲染用的几何体参数是半径1,物理碰撞体和渲染体尺寸不一致会导致后续碰撞效果错位。
- 物理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
相关产品推荐
相关产品推荐

