写在前面
Pawn继承于Actor,增加了一些用于控制和提供玩家视角的功能,这里主要是介绍一下Pawn类的实现。
一、创建一个Pawn的C++类
- 创建的C++类也是放在Source文件夹中的Public和Private文件夹中;
- 选择Pawn作为继承的父类;
- 头文件中除了Actor的函数外,仅额外增加了一个负责设置玩家输入组件的函数
SetupPlayerInputComponent()
,如下:
- 在
.cpp
文件中也默认实现了SetupPlayerInputComponent()
函数,如下:
二、增加摄像机组件
- 摄像机相当于是提供了一个玩家视角;
- 它绑定在Pawn上之后,玩家视角就能随着Pawn移动而移动;
- 头文件实现如下:
- 并在
.cpp
文件中把摄像机组件挂载到根组件上,实现如下:
- 一些补充如下:
1. StaticMesh的网格体形状可以预先设置
- 代码实现如下:
- 一些注意的点如下:
- 首先要用
MeshComponentAsset
变量尝试加载资源; - 如果能加载,则将资源赋予网格体;
- 资源的路径可以通过右键资源->复制引用获得,如下:
- 首先要用
2. 摄像机组件可以和弹簧臂组件组合使用
- 当然直接将摄像机固定在Pawn的某个位置也是可以的,但这样视角移动就会很生硬,在启动和停止时没有过渡动画的效果,实现就是上面那样;
- 但如果使用弹簧臂连接摄像机和Pawn,则视角移动更为自然,这也是常用的做法;
- 首先在头文件中增加弹簧臂组件,如下:
- 然后在构造函数中设置弹簧臂,并将摄像机挂载到弹簧臂上,如下:
- 一些注意的点如下:
- 弹簧臂是挂载在根组件上;
- 摄像机是挂载在弹簧臂的预设插槽(Socket)上;
- 弹簧臂的倾斜角度和长度取决于摄像机想要放置的位置;
3. 可以用某个组件代替默认的根组件
- 默认的根组件只是用于占位,本身并没有作用,因此可以用别的有实际作用的组件替换掉;
- 这里用一个隐藏的更大的球形组件(注意不是球型静态网格组件)替换根组件,并设置为不可见;
- 头文件实现如下:
- 构造函数中实现如下:
三、创建一个Pawn的蓝图类
- Pawn类和Actor类不同,它的很多功能需要用蓝图类辅助实现(当然完全用C++也可以,但会很麻烦,而且不直观,相当于是用文字描述图片了),所以一般是要新建一个和Pawn类对应的蓝图类作进一步开发;
- 由C++创建的蓝图类相当于是继承了C++类;
1. 由C++类创建蓝图类的方法
- (1) 右键C++类,选择创建基于xxx的蓝图类;
- (2) 在内容文件夹下放置蓝图类的路径下,右键->创建基础资源->选择蓝图类,然后在所有类中搜索对应的C++类创建即可;
2. 挂载组件的对应关系
- 在C++类的构造函数中,
RootComponent
下挂载了两个组件,一个静态网格组件,一个是摄像机组件,而且这两个组件处于同一层; - 在蓝图类中的组件面板可以清楚的看到它们之间的挂载结构;
- 按照刚刚的设置,如果不使用弹簧臂,则如下:
- 如果使用弹簧臂,则结构如下:
- 当然,组件也可以在蓝图中继续挂载或者修改;
3. 摄像机组件和Pawn之间的关系
- 摄像机组件实际上是Pawn的一部分;
- 但是它从位置上来说应该有两种情况:
- 第一人称游戏:摄像机组件的位置在Pawn的眼睛位置;
- 第三人称游戏:摄像机组件的位置在Pawn的后上方位置;
- 通常会用另外一个网格组件(这里暂时是用StaticMeshComponent)作为Pawn的本体,也就是充当Pawn生物的外形;
- 按照刚刚在C++类构造函数中的设置,如果不使用弹簧臂组件,则摄像机和静态网格组件之间的位置关系如下图:
- 如果使用弹簧臂组件,则摄像机和静态网格组件之间的位置关系如下图:
四、在地图上以Pawn开始游戏
- Pawn因为可以作为玩家的控制的视角,所以我们需要在开始游戏之后获得某个Pawn的视角,并且能够控制Pawn的运动;
1. 获得Pawn视角
- 如果什么都不设置,默认开始游戏是将视角放到PlayerStart上的,并对准前向(红色箭头),如下:
1.1 在PlayerStart处生成一个Pawn
- 通过设置游戏模式(GameMode),可以在PlayerStart处生成一个Pawn,这样就可以顺理成章地获得它的视角了;
- 通过默认生成的游戏模式C++类(这个是创建C++项目的时候就自动创建了的,里面没有内容,仅继承了
AGameModeBase
类)派生一个游戏模式蓝图类BP_CreatureGameMode
,如下:
- 打开
BP_CreatureGameMode
,修改默认Pawn类为BP_CreaturePawn
,就可以修改开始游戏时在PlayerStart处生成的Pawn;
- 之后,还需要在世界中应用新的游戏模式;
- 在主面板上打开世界场景设置面板,修改其中的游戏模式覆盖为刚刚创建的游戏模式蓝图类即可;
- 此时用选中的视口播放游戏,就可以在PlayerStart处生成我们选定的Pawn,而且视角是在Pawn绑定的摄像机组件上;
1.2 将某个Pawn赋予玩家视角
- 如果是在PlayerStart处生成一个Pawn,是有一些不足的:
- 没有办法赋予它一些预设的实例参数,因为它是一个新生成的实例,完全依赖于C++类或者蓝图类中的默认设置;
- 也没有办法在不同的Pawn之间切换视角,只能一直在PlayerStart视角;
- 这里介绍如何为某个Pawn赋予玩家视角;
- C++实现:
- 只需要在构造函数中设置
AutoProssessPlayer
变量即可:
- 只需要在构造函数中设置
- Editor实现:
- 在细节面板中选中Pawn->自动控制玩家,修改值为玩家0即可:
2. 绑定玩家输入控制
2.1 创建轴映射
- 在Editor中点击编辑->项目设置;
- 在引擎->输入->Bindings里面新增轴映射,如下:
- 输入的映射方式主要有两种:
- 轴映射:输入的设备可提供输入程度的变化范围,输入的是一个连续值,该值会乘以设定的缩放值,然后传给后续响应事件函数中的
float
类型参数Value
; - 操作映射:输入的设备仅提供是否输入的信号,即离散的
0/1
,后续有两个响应事件函数,一个响应按下按钮事件,一个响应释放按钮事件; - 可以参考博文:UE4中轴映射;
- 轴映射:输入的设备可提供输入程度的变化范围,输入的是一个连续值,该值会乘以设定的缩放值,然后传给后续响应事件函数中的
2.2 绑定到响应事件函数
- 在Pawn默认构建的
SetupPlayerInputComponent()
函数中可以绑定映射对应的响应事件函数,实现如下:
- 注意
BindAxis()
函数中的字符串参数就是刚刚在项目设置中创建的轴映射事件名称,必须要相互对应;
3. 实现玩家控制的影响
- 前面只是将玩家输入绑定到Pawn某个成员变量上,并没有对Pawn产生实际的影响;
- 这里将实现对Pawn的影响,也就是令Pawn产生位移,实现如下:
- 上面的代码里面有两种实现,推荐是用第二种类型的;