项目设置

打开Edit/Project Settings,设置绑定

代码实现:

  • 函数声明不需要UPROPERTY修饰

ACharacter类中有一个SetupPlayerInputComponent函数,在该函数中实现输入名称与函数之间的绑定。设置中支持将键盘、鼠标和控制器输入映射到”友好名称”,该名称稍后可以绑定到游戏行为上(例如移动)。该名称稍后可以与事件驱动的行为绑定。

  • 操作映射:对于像跳跃这样,按一下按键触发一次跳跃动作,使用BindAction函数来绑定。操作映射处理离散事件的输入(例如,按下为1,不按下为0),最终效果是,按下和/或释放单个键、鼠标按钮或辅助键盘按钮可以直接触发游戏行为。

  • 轴映射:对于像向前走这样,需要一直按住按键,使用BindAxis函数来绑定。通常,轴映射轴映射会不断被轮询,从而实现无缝的移动过渡和流畅的游戏行为。硬件轴(例如游戏摇杆)所提供的输入值为程度值。虽然游戏摇杆输入方法在提供可平滑伸缩的移动输入方面很有效,但轴映射也可以将常见的移动键(如WASD键或箭头键)映射到持续轮询的游戏行为。

如果你想要了解有关玩家输入的更多信息,参阅玩家输入和Pawn

1
2
3
4
5
6
7
// Called to bind functionality to input
void AScharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){
Super::SetupPlayerInputComponent(PlayerInputComponent);
//第一个参数是指在项目设置中取的名字
PlayerInputComponent->BindAxis("MoveForward", this, &AScharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AScharacter::MoveRight);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//前进,由于是axis的,有一个float类型的参数

void AFPSCharacter::MoveForward(float Value){
if (Value != 0.0f){
// add movement in that direction
AddMovementInput(GetActorForwardVector(), Value);
}
}
void AScharacter::MoveRight(float value) {
if (value != 0.0f) {
AddMovementInput(GetActorRightVector(), value);
}
}

//官方代码:
void AFPSCharacter::MoveForward(float Value)
{
// 找出"前进"方向,并记录玩家想向该方向移动。
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
void AFPSCharacter::MoveRight(float Value)
{
// 找出"右侧"方向,并记录玩家想向该方向移动。
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
AddMovementInput(Direction, Value);
}

测试代码功能:

  1. ctrl + shift + B: 构建(Build)项目。
  2. 构建完毕后,在虚幻引擎中打开 项目。
  3. 在关卡编辑器工具栏中点击 运行(Play)(注意控制的人物是否是设置的那个人物类)。
  4. 退出(Escape) 键或在关卡编辑器中点击 停止(Stop),退出PIE模式。

实现鼠标控制相机转向

上下转向,需要绑定到Mouse Y(鼠标方向Y轴),scale: -1。左右转向绑定到Mouse X(鼠标方向X轴)

  • UE4规定:绕z轴旋转叫Yaw,绕y轴旋转叫Pitch,绕x轴旋转称Row。
  • 人物是面向x正方向的
1
2
3
4
void AScharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){
PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
}

如果鼠标不能够控制旋转,查看弹簧臂中use pawn control rotation是否check

下蹲动作

实现下蹲功能,还需要在构造函数中添加

GetMovementComponent()->GetNavAgentPropertiesRef().bCanCrouch = true;

如果未设置true,则什么也不会发生。

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void AScharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){	
PlayerInputComponent->BindAction("Crouch", IE_Pressed, this, &AScharacter::BeginCrouch);//“按下”时调用函数
PlayerInputComponent->BindAction("Crouch", IE_Released, this, &AScharacter::EndCrouch);//IE_Released(松开按键时调用)
}

//UE4已经实现了下蹲,直接调用Crouch()函数
//下蹲是action,无参,因为不是Axis运动,没有具体的值
void AScharacter::BeginCrouch() {
Crouch();
}

void AScharacter::EndCrouch() {
UnCrouch();
}

如果仍然不能下蹲:

LogCharacter: BP_Player_2 is trying to crouch, but crouching is disabled on this character! (check CharacterMovement NavAgentSettings)

看一下人物蓝图中移动组件的Detail面板中Can Crouch是否check。

实现角色跳跃

Acharacter 类中实现了角色跳跃。我们需要做的就是,在跳跃操作按下时*将bPressedJump设置为true,在跳跃操作释放时将该布尔值设置为false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//头文件:
// 按下键时,设置跳跃标记。
UFUNCTION()
void StartJump();

// 释放键时,清除跳跃标记。
UFUNCTION()
void StopJump();
//源文件:
void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){
// 设置"操作"绑定。
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);
}

void AFPSCharacter::StartJump(){
bPressedJump = true;
}

void AFPSCharacter::StopJump(){
bPressedJump = false;
}

蓝图实现

官方实现的移动:

除了使用Break RotatorMake Rotation结点,还可以直接拆分引脚:

拆分引脚而不是直接相连的必要性:如果使用原始的向量(它的方向),如果视角从上往下看人物并向前移动,人物的移动速度会很慢。

演示

输入axis或aciton,出现的这些是在项目设置input中设置的绑定

相机围绕人物旋转

实现第三人称游戏中的相机与人物的关系(人物不动时滑动鼠标可以围绕人物旋转,人物”向后退“表现的是人物向后转面向相机前进)

需要:

  1. 勾选移动组件中的orient Rotation to Movement

  2. 取消勾选蓝图中的Use Controller Rotation Yaw

问题:用C++代码控制的移动,如果做上面的操作,移动是错的,待解决

猜测:代码实现和蓝图实现不一样