Skip to content

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

Published:

上节加了镜子:

2026-03-08 22.00.35.gif

这节把跳舞的人也加进来:

2025-04-13 20.16.22.gif

https://github.com/mrdoob/three.js/blob/e9144842962d46f0ab4a7049cc072ad201d9659d/examples/models/gltf/Michelle.glb

image.png

在 dancingMirrorHut.js 里加一下:

image.png


// 镜子前面加载 Michelle 跳舞
let dancerMixer = null;
new GLTFLoader(loadingManager).load('./Michelle.glb', (gltf) => {
  const dancer = gltf.scene;
  dancer.scale.setScalar(0.8);
  dancer.position.set(hutOffsetX, hutOffsetY, hutOffsetZ);
  dancer.traverse((obj) => {
    if (obj.isMesh) {
      obj.castShadow = true;
      obj.receiveShadow = true;
    }
  });
  group.add(dancer);

  dancerMixer = new THREE.AnimationMixer(dancer);
  if (gltf.animations[0]) {
    dancerMixer.clipAction(gltf.animations[0]).setLoop(THREE.LoopRepeat).play();
  }
});

const dancerClock = new THREE.Clock();
export function updateDancingMirrorHut() {
  if (dancerMixer) {
    dancerMixer.update(dancerClock.getDelta());
  }
}

这个 update 方法需要在 main.js 里调用下:

image.png

2026-03-08 22.14.00.gif

这样,跳舞的小女孩就加载出来了。

现在没有物理效果:

2026-03-08 22.15.01.gif

然后给他加上物理效果,加一个圆柱就行:

image.png

const dancerRadius = 0.4;
const dancerHeight = 1.4;
let dancerMixer = null;
let dancerBody = null;
dancerBody = new CANNON.Body({
    mass: 0,
    position: new CANNON.Vec3(hutOffsetX, dancerHeight / 2, hutOffsetZ)
});
dancerBody.addShape(new CANNON.Cylinder(dancerRadius, dancerRadius, dancerHeight, 8));
world.addBody(dancerBody);

2026-03-08 22.19.00.gif

案例代码上传了小册仓库

总结

这节我们加上了跳舞的女孩,播放了骨骼动画,以及加上了物理效果。

下节加上玩家的跳舞。

评论