对Pawn类进行扩展,以便响应玩家的输入操作。
创建 Pawn 子类
创建 Pawn 子类, 命名为 MyPawn
. Pawn 是一种可以被控制的 Actor
, 且可以接收来自 Controller 的输入, 因为 Pawn 有一个 SetupPlayerInputComponent 成员函数, 当游戏开始运行时, 系统会调用该函数并将控制器传递给 Pawn 对象.
设置玩家
Pawn 自带的成员变量 AutoPossessPlayer 用于设置该 Pawn 对象是由哪个玩家进行控制的. 或者说它响应哪个玩家的控制器输入. 在 MyPawn 构造函数将它绑定到默认玩家:
// 将该Pawn设为由最小编号玩家控制
AutoPossessPlayer = EAutoReceiveInput::Player0;
添加组件
为了让 MyPawn 在场景中可见, 需要添加一个静态网络组件, 同时需要一个相机组件, 这样相机位置便可以随着 MyPawn 的变化而变化. 并把静态网络组件和相机组件附加到根组件.
现在类定义中添加:
UPROPERTY(EditAnywhere)
USceneComponent* OurVisibleComponent;
UPROPERTY(EditAnywhere) 宏定义使我们可以在编辑器中设置静态网络组件
在构造函数中添加:
// 创建可附加内容的虚拟根组件。
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
// 创建相机和可见对象
UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("OurCamera"));
OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OurVisibleComponent"));
// 将相机和可见对象附加到根组件。偏移并旋转相机。
OurCamera->SetupAttachment(RootComponent);
OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f));
OurCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f));
OurVisibleComponent->SetupAttachment(RootComponent);
为了能够让相机和可见的静态网络组件附加到根组件, 这里创建了一个场景组件 USceneComponent.
相机组件需要包含
#include "Camera/CameraComponent.h"
配置游戏输入
在编辑器中,编辑->项目设置->输入, 在绑定中添加:
操作映射 | ||
---|---|---|
Grow | 空格 | |
轴映射 | ||
MoveX | W | 1.0 |
S | -1.0 | |
MoveY | A | -1.0 |
D | 1.0 |
编写和绑定游戏操作
使用 SetupPlayerInputComponent 进行操作绑定时, 需要提供各个响应的回调函数, 在类定义中定义如下回调函数
//输入函数
void Move_XAxis(float AxisValue);
void Move_YAxis(float AxisValue);
void StartGrowing();
void StopGrowing();
//输入变量
FVector CurrentVelocity;
bool bGrowing;
并在 .cpp 文件中实现这些函数:
void AMyPawn::Move_XAxis(float AxisValue)
{
// 以100单位/秒的速度向前或向后移动
CurrentVelocity.X = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f;
}
void AMyPawn::Move_YAxis(float AxisValue)
{
// 以100单位/秒的速度向右或向左移动
CurrentVelocity.Y = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f;
}
void AMyPawn::StartGrowing()
{
bGrowing = true;
}
void AMyPawn::StopGrowing()
{
bGrowing = false;
}
完成实现后将其绑定到事件
// 在按下或松开"Grow"键时做出响应。
InputComponent->BindAction("Grow", IE_Pressed, this, &AMyPawn::StartGrowing);
InputComponent->BindAction("Grow", IE_Released, this, &AMyPawn::StopGrowing);
// 对两个移动轴"MoveX"和"MoveY"的值逐帧反应。
InputComponent->BindAxis("MoveX", this, &AMyPawn::Move_XAxis);
InputComponent->BindAxis("MoveY", this, &AMyPawn::Move_YAxis);
在 Tick 实现控制
// 根据"Grow"操作处理增长和缩减
float CurrentScale = OurVisibleComponent->GetComponentScale().X;
if (bGrowing)
{
// 一秒内增长到两倍大小
CurrentScale += DeltaTime;
}
else
{
// 以增长速度缩减一半
CurrentScale -= (DeltaTime * 0.5f);
}
// 确保不会降至初始大小以下,或者增至两倍大小以上。
CurrentScale = FMath::Clamp(CurrentScale, 1.0f, 2.0f);
OurVisibleComponent->SetWorldScale3D(FVector(CurrentScale));
// 根据"MoveX"和"MoveY"轴处理移动
if (!CurrentVelocity.IsZero())
{
FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime);
SetActorLocation(NewLocation);
}
网友评论