Skip to content

第三人称飞行

loading

1. 更换控制器

three-tile 的地图模型不依赖 camera、controls,所以可以任意更换控制器,跟上个示例第一人称射击一样,将控制器更换为 FlyControls:

https://threejs.org/docs/?q=fly#examples/zh/controls/FlyControls

TIP

计划下个版本增加使用 FlyControls 控制器的 GLViewer (V0.11.4 已内置)。

2. 飞行

这个没啥讲的,加载一个模型,如小鸟、飞机,根据相机的位置和朝向,控制模型的位置和朝向

ts
const initFly = (viewer: FLViewer, map: tt.TileMap) => {
  const loader = new GLTFLoader();
  // loader.loadAsync("../model/Parrot.glb").then((gltf) => {
  loader.loadAsync("../model/acrobaticPlane_variants.glb").then((gltf) => {
    const model = gltf.scene;
    model.scale.setScalar(10);
    viewer.scene.add(model);

    // 动画
    const mixer = new AnimationMixer(model);
    mixer.clipAction(gltf.animations[0]).play();

    viewer.addEventListener("update", (evt: any) => {
      // 固定在摄像机前面
      model.position.set(0, -500, -2000);
      model.applyMatrix4(viewer.camera.matrixWorld);

      // 飞行高度
      const groundInfo = map.getLocalInfoFromWorld(model.position);
      if (groundInfo) {
        state.modelHeight = model.position.y - groundInfo.point.y;
      }
      // 小鸟距地高度<100m撞死,否则动画飞行
      if (groundInfo && state.modelHeight <= 100) {
        // 撞地死了
        viewer.controls.movementSpeed = 0;
        viewer.autoForward = false;
      } else {
        const target = new Vector3(0, 0, -10000).applyMatrix4(viewer.camera.matrixWorld);
        model.lookAt(target);
        viewer.controls.movementSpeed = 2000;
        // viewer.autoForward = true;
        mixer.update(evt.delta);
      }
    });
  });
};


Released under the MIT License.