最近制作了能开箱即用的UE5鼠标组件,直接拷入一个文件,再拖到场景中,就能使用了,可以控制相机的平移、旋转、缩放
使用方法:
- 拷贝Third-Person.uasset到工程的目录下(百来KB)
- 拖拽Third-Person到场景中的初始位置
- 调整Target Arm Length到合适的臂长(可选)
- 开始游戏
在数字孪生/元宇宙/三维可视化场景中,最常见的用户交互模式是基于第三人称的鼠标操作,这其中包括平移(水平移动)、旋转(绕物体转)、缩放(前进/后退),下面详细记录下编写流程。
第一人称与第三人称的区别
第一人称与第三人称的核心区别在于,人物与相机是否分离:人机一体则是第一人称,人机分离则是第三人称。但无论如何,人物(pawn)与相机(camera)作为一个整体,其物体原点与旋转中心都坐落在人物身上,人物与相机的距离叫做臂长(使用了弹簧臂spring arm),臂长的改变则叫做缩放(zoom)。
键盘鼠标操作与几何变换的对应 | |
---|---|
左键 X轴 | 沿纬线移动 |
左键 Y轴 | 沿经线移动 |
右键 X轴、键盘AD | 左右移动 |
右键 Y轴 | 前后移动(水平面) |
鼠标滚轮、键盘WS | 前后移动 |
鼠标滚轮按下 | 飞到目标位置 |
键盘QE | 上下移动 |
键盘ZC | 调整FoV大小 |
蓝图结构
蓝图类型是一个pawn,根元素是一个弹簧臂(spring arm),这样zoom的时候修改arm长度即可,非常方便。弹簧臂下挂一个相机,相机下再挂一个灯,这样万一移动到封闭空间,可以照亮周围,最后再加一个Floating Pawn Movement,使得运动时更有“惯性”。
激活鼠标
pawn初始化的时候要显示鼠标光标,并启用点击事件,这样后续的操作才有意义。
前进与后退(zoom)
因为相机的朝向始终与弹簧臂共线,因此相机永远面向pawn,前进则表示缩短臂长(靠近pawn),后退表示延长臂长(远离pawn),数字孪生常见的做法是用鼠标滚轮的2个方向来表示zoom,因此有了图中的逻辑:如果监听到滚轮前进则将臂长乘以0.9,若是滚轮后退则将臂长乘以1.1,这样缩放的速度与臂长的长度正相关,最后将臂长限制在1m到1km之间,便满足了我们的需求。
瞬间移动
通常玩家还需要快速飞到鼠标点击的地方,所以利用鼠标中键作为跳跃键,发射一条射线来锁定点击位置,再飞过去,因为有FloatingPawnMovement的存在,并不会“瞬移”过去,而是在几百毫秒内过渡过去,用户体验更佳。
绕物体旋转(orbit)
三维可视化和角色扮演游戏的一个重要区别就是,前者绕物体旋转,后者绕自己旋转,这也是第三人称与第一人称的区别。绕物体旋转可以抽象成一个经纬网:球心是物体,臂长是半径,相机的yaw(纬线)和pitch(经线)都是在球面上运动。
被绕的这个物体就是pawn本身,及焦点,相机旋转时,物体也随之旋转,只不过都是绕焦点旋转。我们玩第三人称RPG游戏的时候,镜头始终在人物背后,旋转时,人物原地转动,但相机则按轨迹运动(orbit)。
因为虚拟球面是二维的,所以相机旋转也是二维的,只有Elevation(升降)与Azimuth(平转)这两个维度(正好鼠标垫也是二维的),对于前方的pawn来说就是Pitch(俯仰)和Yaw(偏航),本质是一样一样的。
最终,相机是下面这样移动的,使用了这么多生动形象的图片,你学会了吗?
我们使用左键或者右键拖拽来实现,代码很简单:直接将二位鼠标输入的连续型参数(Mouse XY 2D-Axis)转换成自身的旋转增量。
水平移动
前面提到,鼠标垫是二维的,但三维旋转有3个维度,因此必须牺牲掉一个维度,所以相机旋转只能偏航(yaw)、俯仰(pitch),无法翻滚(roll).同理,三维移动也有3个维度(x、y、z),鼠标只能实现水平面方向的平移(x、y),舍弃掉竖直方向的移动(z)。
鼠标沿横轴移动时,只需要让pawn沿自身坐标系的Y轴移动即可,但鼠标纵轴移动时,情况稍微复杂一点,pawn需要沿着面前的世界水平线运动,也就是俯仰时,弹簧臂扫过的平面与水平面的交线,然后计算这条线在自身坐标系中的X、Z分量(与Y轴垂直)。便有了上图中的蓝图代码。
还有个需要注意的地方,想要将Third-Person.uasset直接拖入场景就能用,得开启“自动激活”的选项:Auto Process Player