虚幻5入门,MashRunner项目2
一.加入移动
在Runner.h中,新加入一些类的声明,并声明一些新的结构成员变量和函数,为了省事,直接搬过来了
#pragma once
#include "CoreMinimal.h"
#include "PaperCharacter.h"
#include "Runner.generated.h"
class UInputMappingContext;
class UInputAction;
class UPaperFlipbook;
UCLASS()
class MASHRUNNER_API ARunner : public APaperCharacter
{
GENERATED_BODY()
public:
//输入上下文,以及动作
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UInputMappingContext> MappingContextRunner;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UInputAction> ActionPowerLeft;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UInputAction> ActionPowerRight;
//静止状态的精灵翻页书
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UPaperFlipbook> IdlePaperFlipbook;
//运动状态的精灵翻页书
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UPaperFlipbook> RunPaperFlipbook;
virtual void Tick(float delta);
virtual void BeginPlay();
private:
//每秒钟速度减少的值
int DecreaseSpeedPerSecond = 300;
//按键提升速度的值
int IncreaseSpeedValue = 60;
//最大移动速度
float MaxMoveSpeed = 1500;
//按键触发的函数,提升速度
void IncreaseSpeeedFunc();
//左键和A键按下后发生的事件
void EventPowerLeft();
//右键和D键按下后发生的事件
void EventPowerRight();
};
对之前的实现做一些修改,并加入新的实现,还要包括新的头文件
#include "Kismet/GameplayStatics.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "InputAction.h"
#include "InputMappingContext.h"
#include "PaperFlipbookComponent.h"
#include "Runner.h"
void ARunner::BeginPlay()
{
Super::BeginPlay();
//如同上一个例子,取得世界中第一个玩家的控制权,并将控制权转到Runner类上
APlayerController* PlayerController = UGameplayStatics::GetPlayerController(this->GetWorld(), 0);
//添加映射上下文
if (PlayerController)
{
PlayerController->Possess(this);
UEnhancedInputLocalPlayerSubsystem* LocalPlayerSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer());
if (LocalPlayerSubsystem)
{
LocalPlayerSubsystem->AddMappingContext(MappingContextRunner, 0);
}
}
//绑定动作
UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(this->InputComponent);
if (EnhancedInputComponent)
{
EnhancedInputComponent->BindAction(ActionPowerLeft, ETriggerEvent::Started, this, &ARunner::EventPowerLeft);
EnhancedInputComponent->BindAction(ActionPowerRight, ETriggerEvent::Started, this, &ARunner::EventPowerRight);
}
//初始状态让玩家保持静止
UCharacterMovementComponent* CharacterMovementComponent = this->GetCharacterMovement();
if(CharacterMovementComponent)
{
CharacterMovementComponent->MaxWalkSpeed = 0.;
}
}
void ARunner::Tick(float delta)
{
this->AddMovementInput(FVector(1.0, 0., 0.));
UCharacterMovementComponent* CharacterMovementComponent = this->GetCharacterMovement();
if (CharacterMovementComponent)
{
CharacterMovementComponent->MaxWalkSpeed = CharacterMovementComponent->MaxWalkSpeed - delta * DecreaseSpeedPerSecond;
}
//在运动时切换至移动的精灵翻页书,否则就是静止状态的精灵翻页书
UPaperFlipbookComponent* PaperFlipbookComponent = this->GetSprite();
float CurrentSpeed = CharacterMovementComponent->Velocity[0];
if (CurrentSpeed >= 1e-9)
{
PaperFlipbookComponent->SetFlipbook(RunPaperFlipbook);
//根据速度更改翻页书的播放速率
PaperFlipbookComponent->SetPlayRate(CurrentSpeed / MaxMoveSpeed);
}
else
{
PaperFlipbookComponent->SetFlipbook(IdlePaperFlipbook);
PaperFlipbookComponent->SetPlayRate(1);
}
}
void ARunner::IncreaseSpeeedFunc()
{
UCharacterMovementComponent* CharacterMovementComponent = this->GetCharacterMovement();
if (CharacterMovementComponent)
{
CharacterMovementComponent->MaxWalkSpeed += IncreaseSpeedValue;
if (CharacterMovementComponent->MaxWalkSpeed <= 0)
CharacterMovementComponent->MaxWalkSpeed = 0;
}
}
void ARunner::EventPowerLeft()
{
IncreaseSpeeedFunc();
//GEngine->AddOnScreenDebugMessage(-1, 2.0, FColor::Green, FString(TEXT("Left")));
}
void ARunner::EventPowerRight()
{
IncreaseSpeeedFunc();
//GEngine->AddOnScreenDebugMessage(-1, 2.0, FColor::Red, FString(TEXT("Right")));
}
编译后进入到虚幻编辑器,编辑蓝图类BP_Runner,选择两个状态使用的精灵

运行游戏,按下对应的键盘按键就能够触发运动,还有翻页书的切换
二.改进输入
先前的输入两个按键随便按都会增加速度,现在想让只当两个按键交替按下才会加速
先在Runner.h中添加一个枚举类
UENUM(BlueprintType)
enum class EInputState : UINT8
{
None UMETA(DisplayName = "None"),
Left UMETA(DisplayName = "Left"),
Right UMETA(DisplayName = "Right")
};
然后给Runner类添加一个成员变量,用来标识上一次的按键状态
public:
//判断上一次的按键
EInputState LastInputState = EInputState::None;
然后再到Runner.cpp中,修改加速度的实现
void ARunner::EventPowerLeft()
{
switch (LastInputState)
{
case EInputState::None:
IncreaseSpeeedFunc();
LastInputState = EInputState::Left;
break;
case EInputState::Left:
break;
case EInputState::Right:
IncreaseSpeeedFunc();
LastInputState = EInputState::Left;
break;
default:
break;
}
//GEngine->AddOnScreenDebugMessage(-1, 2.0, FColor::Green, FString(TEXT("Left")));
}
void ARunner::EventPowerRight()
{
switch (LastInputState)
{
case EInputState::None:
IncreaseSpeeedFunc();
LastInputState = EInputState::Right;
break;
case EInputState::Left:
IncreaseSpeeedFunc();
LastInputState = EInputState::Right;
break;
case EInputState::Right:
break;
default:
break;
}
//GEngine->AddOnScreenDebugMessage(-1, 2.0, FColor::Red, FString(TEXT("Right")));
}
三.非线性的加减速
原先加速度和减速度是衡定的,加入一个曲线,让加速度在速度慢的时候大,在速度快的时候小,而减速度则相反
在虚幻编辑器内容根目录创建一个文件夹Curve,在其中创建一个Float曲线,命名为C_AccelerateCurve,如下编辑曲线。差值选择三次插值自动曲线,关键帧分别为(0,1),(1500,0.2)

同样的,在Curve文件夹中建立一个名为C_DecelerateCurve的曲线,关键帧为(0,0),(1500,1)

然后到VS,在Runner.h中,在Runner类里声明成员变量
public:
//控制加速度的曲线
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UCurveFloat> AccelerateCurve;
//控制减速度的曲线
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UCurveFloat> DecelerateCurve;
在Runner.cpp中,修改一下实现
void ARunner::Tick(float delta)
{
this->AddMovementInput(FVector(1.0, 0., 0.));
UCharacterMovementComponent* CharacterMovementComponent = this->GetCharacterMovement();
if (CharacterMovementComponent)
{
CharacterMovementComponent->MaxWalkSpeed = CharacterMovementComponent->MaxWalkSpeed -
delta * DecreaseSpeedPerSecond * DecelerateCurve->GetFloatValue(CharacterMovementComponent->MaxWalkSpeed);
}
//在运动时切换至移动的精灵翻页书,否则就是静止状态的精灵翻页书
UPaperFlipbookComponent* PaperFlipbookComponent = this->GetSprite();
float CurrentSpeed = CharacterMovementComponent->Velocity[0];
if (CurrentSpeed >= 1e-9)
{
PaperFlipbookComponent->SetFlipbook(RunPaperFlipbook);
//根据速度更改翻页书的播放速率
PaperFlipbookComponent->SetPlayRate(CurrentSpeed / MaxMoveSpeed);
}
else
{
PaperFlipbookComponent->SetFlipbook(IdlePaperFlipbook);
PaperFlipbookComponent->SetPlayRate(1);
}
}
void ARunner::IncreaseSpeeedFunc()
{
UCharacterMovementComponent* CharacterMovementComponent = this->GetCharacterMovement();
if (CharacterMovementComponent && AccelerateCurve)
{
//GEngine->AddOnScreenDebugMessage(-1, 2.0, FColor::Green, FString::Printf(TEXT("%f"), AccelerateCurve->GetFloatValue(CharacterMovementComponent->MaxWalkSpeed)));
CharacterMovementComponent->MaxWalkSpeed += IncreaseSpeedValue * AccelerateCurve->GetFloatValue(CharacterMovementComponent->MaxWalkSpeed);
if (CharacterMovementComponent->MaxWalkSpeed <= 0)
CharacterMovementComponent->MaxWalkSpeed = 0;
}
}
编辑BP_Runner,选择加速度和减速度曲线后就OK了,感觉比蓝图简洁不少

在虚幻编辑器页面,把地面拉长一点


浙公网安备 33010602011771号