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;
};