Skip to content

2. 第三人称飞行

loading

threejs 提供了 FlyControls 控制器,能够真实模拟飞行场景,但官方示例 ( https://threejs.org/examples/?q=fly#misc_controls_fly ) 根本看不懂控制器在干啥,感觉完全失控了。其实 FlyControls 是一个非常好的控制器,可用于飞行游戏,用键盘或鼠标控制飞机,像飞机一样翻滚,只是作者没有写出好的示例,未能体现出它的价值。

将场景控制器更换为 FlyControls,添加一个飞机模型,仅需数十行代码即可完成一个第三人称飞行游戏。

1. 更换控制器

three-tile 的地图模型不依赖特定 controls,所以可以更换任意控制器,跟上个示例第一人称射击一样,将控制器更换为 FlyControls ( https://threejs.org/docs/?q=fly#examples/zh/controls/FlyControls)

2. 飞行

加载一个模型,如小鸟、飞机,固定在摄像机前面,FlyControls 会自动完成飞行控制功能。

ts
/**
 * 初始化飞行模型
 * @param viewer 场景查看器
 * @param map 地图
 * @param onfly 飞行回调
 * @returns 飞行模型
 */
export const initFly = async (viewer: FLViewer, map: tt.TileMap, onfly?: (height: number, evt: any) => void) => {
    const loader = new GLTFLoader();
    const gltf = await loader.loadAsync("../model/acrobaticPlane_variants.glb");
    const model = gltf.scene;
    model.scale.setScalar(1000);
    const mixer = new AnimationMixer(model);
    mixer.clipAction(gltf.animations[0]).play();

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

        // 地面高度
        const groundHeight = map.getLocalInfoFromWorld(model.position)?.point.y || 0;
        // 飞行高度
        const flyHeight = model.position.y - groundHeight;

        if (flyHeight > -50) {
            // 调整机头方向
            const target = new Vector3(0, 0, -10000).applyMatrix4(viewer.camera.matrixWorld);
            model.lookAt(target);
            mixer.update(evt.delta);
        }

        // 飞行回调
        onfly && onfly(flyHeight, evt);
    });

    return model;
};

Released under the MIT License.