之前遇到开门效果,猜测只是旋转mesh的rotation而已,没想到和我想象的有些区别,这里记录一下。
先看一下目前情况,原项目是在网上看到的,发现箱顶的旋转有些诡异,决定练练手,看看能不能改进一下。
原项目链接:wrongakram/React-Three-Minecraft-Chest: Using React Three Fiber we will make a minecraft chest (github.com)
快速预览:React App (react-three-minecraft.netlify.app)
目标:将箱顶旋转改为贴合箱子旋转
网上找到两种方法,一种是通过计算旋转后的物体位置,然后设置对应position,这种比较麻烦,
[vue使用three.js实现盒子上下左右开关门的效果](https://blog.csdn.net/qq_39165556/article/
details/91870533)
另一种是将外部包一层group后,设置mesh的相对位置,然后只需要旋转外部的group就可以了,这个比较巧妙,我决定使用第二种。
首先将箱盖包裹起来,这里用group包裹,将group的position设置为0,0,0,然后将group的position设置为箱子的顶部位置,这样就可以通过旋转group来实现箱子的开合效果了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| return ( <a.group position={[0, -0.99, 0]} onClick={handleAnimation} ref={group} {...props} dispose={null}> {/* 包裹原有mesh,将位置设置为原mesh位置 */} <a.group position={[ -1.4557723082564422e-11, 1.7300409078598022, -0.9812345504760742 ]} rotation={chestOpen.rotation} > {/* 仅仅用来展示group位置 */} <a.mesh position={[0, 0, 0]} > <boxBufferGeometry attach="geometry" args={[1, 1, 1]} /> <meshBasicMaterial color={0x000000} wireframe /> </a.mesh> {/* 箱盖 */} <a.primitive object={nodes.Bone001} position={[0, 0, 0]} /> </a.group> {/* 箱子体 */} <primitive object={nodes.Bone} />
<skinnedMesh castShadow receiveShadow material={materials.Material} geometry={nodes.Cube.geometry} skeleton={nodes.Cube.skeleton} /> </a.group> );
|
先看一下当前的效果
线框代表group,现在只需要将group向左下方移动,然后将mesh复原回原来的位置就可以了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| return ( <a.group position={[0, -0.99, 0]} onClick={handleAnimation} ref={group} {...props} dispose={null}> <a.group position={[ -1.4557723082564422e-11 - offset, 1.7300409078598022 - offset, -0.9812345504760742 ]} rotation={chestOpen.rotation} > <a.mesh position={[0, 0, 0]} > <boxBufferGeometry attach="geometry" args={[1, 1, 1]} /> <meshBasicMaterial color={0x000000} wireframe /> </a.mesh>
<a.primitive object={nodes.Bone001} position={[offset, offset, 0]} /> </a.group> <primitive object={nodes.Bone} />
<skinnedMesh castShadow receiveShadow material={materials.Material} geometry={nodes.Cube.geometry} skeleton={nodes.Cube.skeleton} /> </a.group> );
|
最终效果: