一、输入系统界面的一些基本概念
1、Action Mappings
这个动作映射是指瞬时动作完成后所要执行的事件,比如按下键盘空格键就执行玩家角色跳跃函数,松开空格键就执行玩家角色停止跳跃函数。
上图的"Jump"是其中的一个动作映射,触发方式有键盘空格键还有手柄,具体的动作有按下和释放两种,这两种动作可以绑定不同的函数,比如按下键盘空格键就执行玩家角色跳跃函数,松开空格键就执行玩家角色停止跳跃函数。C++中具体绑定方式如下图。
2、Axis Mappings
这个轴映射是指连续动作完成后所要执行的事件,比如按住键盘W键玩家角色向前移动,按住键盘S键玩家角色向后移动。
上图的"MoveForward"是其中的一个轴映射,控制玩家角色前后移动,触发方式有键盘W键、S键、向上箭头键、向下箭头键还有手柄,具体的动作只有按住一种方式,输入系统会根据玩家按住的时间长短计算出移动距离。
这个Scale是指玩家角色移动的方向和移动距离的缩放大小,Scale为正数则是向前移动,负数则是向后移动,Scale值越大,则移动距离就越大,一般Scale的绝对值都是1。C++中具体绑定方式如下图。
2.1、其他一些轴事件
MoveRight是控制玩家角色左右移动事件
TurnRate是控制玩家角色左右旋转事件
可以通过键盘左箭头控制玩家角色摄像机向左移动,通过键盘右箭头控制玩家摄像机向右移动。以及还可以通过手柄控制。也不知为啥要加上个Rate,一开始我还以为是转向速率。。。
LookUpRate控制玩家角色摄像机上下旋转。
只能通过手柄来触发。因为键盘的向上箭头和向下箭头已经被用来控制玩家角色前后移动了。
Turn也是控制玩家角色摄像机左右旋转。
只要鼠标向右移动,则玩家角色摄像机就会向右移动,反之如果鼠标向左移动,则玩家角色摄像机就会向左移动。这里的鼠标移动你按不按住鼠标左键和右键以及滑轮也就是中键,结果都一样的。
LookUp也是控制玩家角色摄像机上下旋转
只要鼠标向上移动,则玩家角色摄像机就会向上移动,反之如果要鼠标向下移动,则玩家角色摄像机就会向下移动。这里的Scale之所以是-1是因为屏幕坐标系统中,原点在左上角。假设摄像机向上移动是正数,向下移动是负数,那么当鼠标光标从下方移动到上方时,移动的值是负数,再乘与Scale(-1)就会变成正数,摄像机则向上移动。
二、跟着源码跑一遍流程
1、事件的注册和触发流程
从C++的Main函数到while循环到引擎的tick循环函数到生成引擎对象、游戏对象、玩家对象、玩家角色的输入系统创建的流程如下图
我们接着看玩家角色绑定事件的具体过程。这里用动作映射事件举例。
这里将所有的动作映射事件代理(ActionDelegate)都存放到ActionBindings数组中。
具体的每个的动作映射事件所要执行的函数存放在 FuncDelegate中,以便触发事件时调用该函数。
有一个Tick循环函数在监听玩家的输入操作,当玩家鼠标按下时,把玩家的输入事件存放在KeyStateMap中。
同时有另一个Tick函数处理KeyStateMap里的事件,最终触发ActionDelegate的FuncDelegate
2、注意事项
最后有一个要注意的是,【项目设置】的Use Mouse for Touch一旦勾选上了,屏幕这里会显示模拟摇杆,并且动作映射触发方式为鼠标左键的事件无法触发。这里以我新建的测试动作事件为例。
就是鼠标左键点击后无法执行到我测试用的test函数。
原因是FSlateApplication::OnMouseDown这里有个bIsGameFakingTouch的判断,也就是游戏是否开启模拟触摸。
当Use Mouse for Touch勾选了,并且是鼠标左键时,就会将动作事件转成触摸事件,会执行TouchDelegate,不会执行ActionDelegate
PlayerInput.cpp
设置bIsGameFakingTouch的流程如下图