给箱子添加开箱效果
孙泽辉 Lv5

之前遇到开门效果,猜测只是旋转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)

image

目标:将箱顶旋转改为贴合箱子旋转

网上找到两种方法,一种是通过计算旋转后的物体位置,然后设置对应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>
);

先看一下当前的效果

image

线框代表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>
);

最终效果:

image
 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
Total words 87.1k