开个天坑,UE5.1.1的移动代码做了一个大更新,对于我这种万年蓝图然后正在转C++的人来说可以说是个挑战也可以说是个更方便我去工作的一个点。同时斯坦福大学的那个教程的开头几个章节就不适用了,对于学习UE5.1.1的同学来说。所以我这里会尽量每天跟着斯坦福的教程走同时把学习到的东西(包括但不限于课堂的作业和ue的新特性如何使用的问题)写到博客上。
废话少说,先上对于我来说较为重磅的一个点:增强上下文输入。
我在B站上面看到没人写,也没有人讲这个东西,所以干脆自己从官方的第三人称游戏入手,先看看官方的代码是怎么写的以及是怎么设置的。
官方的代码我这里就不重复输入了,我的博客里面有用中文注释写过一个我对于官方代码的理解,链接在这里
UE5.1.1版本第三人称模板Character C++文件分析
我分析完代码之后,想着自己上手先照着代码抄一遍加深理解,于是开了个空的项目从头开始实现这些功能。但是遇到了一个大问题,那就是一个报错。
解决方案:
错误原因一:
报错原因是组件的BlueprintReadOnly属性只能在private状态内声明,不然就会出错。
错误原因二:
我们的空项目内的Build.cs文件内是不会有EnhancedInput这个插件包的声明的,我们需要在AddRange函数后面加上这个包的包名。
以上两个问题是我在自己尝试重现功能的时候遇到的问题。
下面是我的创建的character类的.h文件以及.cpp文件
SCharacter.h文件
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
//需要在Build.cs文件中添加EnhancedInput路径,UE才能识别到InputActionValue.h头文件
#include "InputActionValue.h"
#include "SCharacter.generated.h"
UCLASS(config = Game)
class ACTIONROGUELIKE_API ASCharacter : public ACharacter
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere)
class USpringArmComponent* SpringArmComp;
UPROPERTY(VisibleAnywhere)
class UCameraComponent* CameraComp;
UPROPERTY(EditAnywhere, Category = Input)
class UInputMappingContext* DefaultMappingContext;
UPROPERTY(EditAnywhere, Category = Input)
class UInputAction* MoveAction;
UPROPERTY(EditAnywhere, Category = Input)
class UInputAction* JumpAction;
public:
// Sets default values for this character's properties
ASCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
protected:
void Move(const FInputActionValue& Value);
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
SCharacter.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "SCharacter.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/Controller.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
//#include "../../../../../UE_5.1/Engine/Plugins/EnhancedInput/Source/EnhancedInput/Public/EnhancedInputSubsystems.h"
//#include "../../../../../UE_5.1/Engine/Plugins/EnhancedInput/Source/EnhancedInput/Public/EnhancedInputComponent.h"
// Sets default values
ASCharacter::ASCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
SpringArmComp->SetupAttachment(RootComponent);
CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
CameraComp->SetupAttachment(SpringArmComp);
}
// Called when the game starts or when spawned
void ASCharacter::BeginPlay()
{
Super::BeginPlay();
if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
}
void ASCharacter::Move(const FInputActionValue& Value)
{
FVector2D MovementVector = Value.Get<FVector2D>();
if (Controller!=nullptr)
{
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(ForwardDirection, MovementVector.Y);
AddMovementInput(RightDirection, MovementVector.X);
}
}
// Called every frame
void ASCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ASCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
{
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ASCharacter::Move);
}
}