上节实现了方向调整:

这节来做一下左右移动,以及往上往下看的功能。
首先,如何确定左右方向呢?
这个可以通过叉乘得到:

a 和 b 向量的叉乘,可以得到一个垂直于 a、b 的向量。
那我们有了向上的向量,有了前进的方向向量,叉乘不就可以得出左边或者右边的向量么?
然后朝那个方向移动就好了。
写一下:

else if(keyPressed.a) {
if(!flag) {
changeAction?.(false);
}
flag = true;
const frontDir = camera.getWorldDirection(new THREE.Vector3());
const topDir = new THREE.Vector3(0, 1, 0);
const dir = topDir.cross(frontDir);
if(v.length() < 400) {
v.add(dir.multiplyScalar(a * deltaTime));
}
}
其余代码一样,核心是中间那三行代码。
我们拿到向前的方向向量,向上的向量,叉乘就可以得到向左的方向向量。
试一下:

没问题。
向右也是一样:

else if(keyPressed.d) {
if(!flag) {
changeAction?.(false);
}
flag = true;
const frontDir = camera.getWorldDirection(new THREE.Vector3());
const topDir = new THREE.Vector3(0, 1, 0);
const dir = frontDir.cross(topDir);
if(v.length() < 400) {
v.add(dir.multiplyScalar(a * deltaTime));
}
}
只不过把叉乘的计算顺序反一下。

这样,向左、向右移动就实现了。
那向上向下看呢?
之前不是调整了相机方向,再获取相机方向来移动就不对了么?
其实只要获取方向的时候把 y 的方向设为 0 就可以了。
首先,让鼠标可以控制相机上下的方向:

camera.rotation.x += e.movementY / 500;
相机的向上向下看用鼠标来控制。
看下效果:

然后前进、后退的时候,把 y 方向的速度去掉,这样就会在水平的平面内走了:

dir.y = 0;
试一下:

至此,向左、向右、向前、向后,调整方向,往上往下看,静止和走路的动画切换就都实现了。
刚发现向后的速度少一个负号,加一下:

整体看一下:
向前:

向后:
向左:

向右:

改变方向:

往上往下看:

都没问题。
案例代码上传了小册仓库
总结
这节我们实现了向左、向右走,往上往下看的功能。
向左、向右的方向是通过向前、向上的方向向量叉乘得到的。
叉乘可以拿到垂直于两个向量的向量。 这点很多情况下会用到。
然后往上往下看就是通过鼠标的 movementY 来调节 camera.rotation
但是移动的时候要把 y 轴的速度去掉,只在水平方向移动。
这样,我们的玩家第一人称漫游的完整功能就完成了。