Skip to content

216. 综合实战:开放世界(十七)

Published:

上节给房屋加上了物理效果,然后画了窗户:

2026-01-03 21.00.05.gif

2026-01-03 20.48.00.gif

这节给屋内加上一张桌子,然后上面放一台电脑,后面可以靠近电脑按 E 开始打电脑。

我们用之前做 3D 电脑时候的模型:

https://sketchfab.com/3d-models/desktop-monitor-low-poly-a30bb55b7e774b1fa696edbee9588835\#download

image.pnghttps://sketchfab.com/3d-models/computer-desk-05353724b7884bfb81211c7033a57fd4

image.png

放 public 目录下:

image.png

创建 src/computer.js

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const loader = new GLTFLoader();

export function loadComputer(group, houseOffsetX, houseOffsetY, houseOffsetZ, roomDepth) {
    loader.load("./monitor.glb", function (gltf) {
        console.log(gltf);
        gltf.scene.scale.set(0.5, 0.5, 0.5);

        // 将显示器放置在房子内部
        gltf.scene.position.set(
            houseOffsetX + 0,
            houseOffsetY + 1,
            houseOffsetZ + (-roomDepth / 2)
        );
        
        group.add(gltf.scene);

        gltf.scene.traverse(obj => {
            if (obj.isMesh) {
                obj.castShadow = true;
            }
        });
    });

    loader.load("./desk.glb", function (gltf) {
        // console.log(gltf);
        gltf.scene.scale.set(0.3, 0.3, 0.3);
        gltf.scene.rotateY(Math.PI / 2);
        
        // 将桌子放置在房子内部,显示器下方
        gltf.scene.position.set(
            houseOffsetX + 0,
            houseOffsetY + 1,
            houseOffsetZ + (-roomDepth / 2)
        );
        
        group.add(gltf.scene);

        gltf.scene.traverse(obj => {
            obj.receiveShadow = true;
        });
    });
}

加载 desk 和 computer,设置下 scale 和 position

看下效果:

2026-01-11 21.06.32.gif

桌子和电脑渲染出来了。

但是现在没有物理效果,人可以穿过桌子。

我们加一下桌子的刚体。

image.png

首先用包围盒拿到模型的尺寸。

然后设置 Box 形状的物理刚体。

最后加一下可视化的线框。

// 计算桌子的边界框来确定物理体大小
const box = new THREE.Box3();
box.setFromObject(gltf.scene);
const size = box.getSize(new THREE.Vector3());
const center = box.getCenter(new THREE.Vector3());

// 创建桌子的物理刚体
const deskBody = new CANNON.Body({
    mass: 0, // 静态物体,质量为0
    position: new CANNON.Vec3(center.x, center.y, center.z)
});
deskBody.addShape(new CANNON.Box(new CANNON.Vec3(
    size.x / 2,
    size.y / 2,
    size.z / 2
)));
world.addBody(deskBody);

// 可视化物理刚体 - 创建线框盒子
const helperGeo = new THREE.BoxGeometry(size.x, size.y, size.z);
const helperMat = new THREE.MeshBasicMaterial({
    color: 0x00ff00,
    wireframe: true,
    transparent: true,
    opacity: 0.5
});
const helperMesh = new THREE.Mesh(helperGeo, helperMat);
helperMesh.position.copy(center);
group.add(helperMesh);

看一下:

2026-01-11 21.21.02.gif

这样,桌子的物理效果就加好了。

可以去掉线框了。

image.png

案例代码上传了小册仓库

总结

这节我们在房屋内加了电脑和桌子。

并且加上了对应的物理效果。

下节就可以加上电脑屏幕里的网页,以及实现打电脑效果了。

评论