ITman彪叔的博客,微信公众号:ITman彪叔。欢迎对canvas、webgl、图形学感兴趣的读者订阅专栏。 点击下面链接可以订阅: [canvas高级进阶] https://xiaozhuanlan.com/canvas [webgl入门到高级进阶]https://xiaozhuanlan.com/webgl

UE 实现镜头平移,旋转和缩放

0x00 引

在数字孪生三维场景中,通过键盘和鼠标来控制镜头的移动,缩放是很常见的行为,也是很必要的行为,用户正是通过这些操作,达到对整个三维场景的观看和控制。

0x01 键盘控制镜头前后左右移动

通常,我们会通过几个键盘来控制镜头的移动,比如W向前,S向后,A向左,D向右。
如果是开发过threejs的读者,可能能够设想到的思路是这样的,监听键盘事件,如果是字母W就是把镜头的位置和中心点向前移动,其他键类似。

不过UE把相关的类似的操作封装成了新的事件,通过在项目中配置,可以得到相关的事件的映射,如下图所示,在项目配置中(编辑 -> 项目设置 -> 输入):

image.png
如上图所示,W和向上键映射了向前的MoveForward事件,S和向下键映射了向后MoveForward事件。 因此监听MoveForward事件即可实现镜头的向前、向后移动。 同理监听MoveRight事件可以实现向右、向左移动。

添加摄像头组件

接着上一篇文章 《UE 实现鼠标点选模型》,打开A_Pawn蓝图类,添加摄像头组件

image.png

添加完成后如下所示:

image.png

添加完成后,就可以通过对Pawn的控制来达到对镜头的控制。因为镜头是改Pawn的孩子,Pawn的改变会影带动镜头的变化。

添加"浮动pawn移动"组件

"浮动pawn移动"组件为Pawn类提供了简单的运动的能力,指定"浮动pawn移动"组件之后,Pawn类就可以被控制移动。

添加"浮动pawn移动"组件:

image.png

添加之后可以看到:

image.png

监听MoveForward事件实现前后移动

在蓝图中添加MoveForward事件:

image.png

image.png

其中Axis Value表示事件的缩放值(1表示向前,-1表示向后)。监听到了MoveForward之后,就是控制Pawn的前后移动,通过“添加移动输入” 可以控制Pawn的移动:

image.png

其中目标是Pawn类,此处使用self即可(Pawn类自身,World Direction表示移动的方向,Scale Value 表示移动的缩放值,一般1表示向前,-1向后,这个正好和前面的Axis Value可以对应。

获取Pawn自身的旋转方向作为World Direction的输入。通过获取控制旋转,然后在通过控制旋转获取向前的向量获取Pawn向前的向量。如果你熟悉webgl和threejs,此步骤类似于下面这个函数:

/**
 * 获取网元的正前方向量
 * @method frontDirection
 * @return {Vec3} 返回网元的正前方向量
 */
frontDirection : function() {
    var n = new $Vec3(0, 0, 1);
    n = n.applyMatrix4(new Mat4().extractRotation(this.matrixWorld));
    n.normalize();
    return n;
},

如下图所示:

image.png

最终全部的蓝图如下:

image.png

监听MoveRight事件实现左右移动

这和 “监听MoveForward事件实现前后移动”类似,此处不在详细说明,全部蓝图如下:

image.png

0x02 鼠标移动控制镜头旋转

UE有两个鼠标事件“鼠标X”、“鼠标Y”分别表示鼠标X方向和Y方向的移动。

image.png

鼠标X事件实现镜头左右旋转

在监听了鼠标X事件后,需要设置镜头的旋转,通过下面的蓝图节点,可以设置Pawn的旋转。

image.png

image.png

其中目标是Pawn自己,New Rotation表示要设置的新的旋转的值,是一个向量,该属性还可以进行分割成三个分量,x,y,z。之所以要分割是因为我们左右旋转,只需要改变Z轴方向的旋转。

image.png

image.png

后续涉及到的分割结构体引脚和此处类似,可能不会在单独说明。

首先需要获取原本的旋转值,然后在原本的旋转值基础上,加上一个新的增量。获取Pawn的旋转,可以通过“获取控制旋转”获取控制器的当前的旋转值:

image.png

改节点的目标是控制器,所以需要获取控制器作为目标的输入:

image.png

在原来的Z轴旋转的基础上,加上一个增量,这个增量就是“鼠标X”节点的Axis Value,不过一般来说,Axis Value 会比较小,所以还会先乘以一个倍数,把相称的结果作为增量。把Z轴旋转添加增量之后的值,赋值给“设置控制旋转”节点的Z旋转值。

整体的蓝图流程如下:

image.png

判断鼠标是否按下

一般来说,我们要旋转镜头,需要按下鼠标,然后移动才能旋转。所以我们需要添加一个条件判断,首先通过下面的节点,可以判断鼠标是否按下:

image.png

其中目标是玩家控制器,所以需要获取玩家控制器并连接上

image.png

其中的key 设置为鼠标左键,表示判断鼠标左键的按下情况。该节点也可以判断其他键的按下情况。

然后添加一个条件分支,把上述节点的结果作为条件分支节点的输入条件:

image.png

整体的蓝图流程如下:

image.png

鼠标Y事件实现镜头上下旋转

鼠标Y事件实现镜头上下旋转和“鼠标X事件实现镜头左右旋转”,此处不再赘述,区别的地方在设置的是X轴的旋转。
整体的蓝图流程如下。

image.png

0x03 鼠标滚轮控制镜头缩放

实现滚轮缩放,需要使用到 弹簧臂组件。 首先在蓝图的添加一个弹簧臂组件,如下图所示:

image.png

添加之后的,需要把弹簧臂加做camera的父亲,这样弹簧臂的改变会带着镜头一块改变:

image.png

弹簧臂组件有一个长度属性,通过改变这个长度,就能达到伸缩的效果。

首先监听鼠标滚轮事件:

image.png

然后设置弹簧臂的长度,可以拖拽弹簧臂组件到蓝图中:

image.png

要设置长度,先要获取原本的长度,

image.png

最后在原本长度上面增加一个长度,全部的蓝图如下所示:

image.png

0x04

本文讲述了通过蓝图实现镜头的平移旋转,旋转和缩放,涉及到了很多的知识点,需要仔细耐心的查看。

如果你有好的经验,也欢迎和我交流。关注公号“ITMan彪叔” 可以添加作者微信进行交流,及时收到更多有价值的文章。

posted on 2022-09-02 07:56  ITman彪叔  阅读(648)  评论(0编辑  收藏  举报

导航

ITman彪叔的博客,微信公众号:ITman彪叔。欢迎对canvas、webgl、图形学感兴趣的读者订阅专栏。 点击下面链接可以订阅: [canvas高级进阶] https://xiaozhuanlan.com/canvas [webgl入门到高级进阶]https://xiaozhuanlan.com/webgl