虚幻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了,感觉比蓝图简洁不少

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

posted @ 2025-04-02 17:56  SuzumiyaYui  阅读(48)  评论(0)    收藏  举报