跳到主内容
Documentation

1.实现角色移动,查看,跳跃.md

2025/12/16预计阅读 13 分钟

1.创建一个AMyCharacterc++类

它继承虚幻角色类,类名是ACharacter

2.重写父类SetupPlayerInputComponent函数绑定输入,添加动作监听

1.在角色类中定义2个属性,(输入映射UInputMappingContext)和(动作UInputAction)


class DEMO2_API AMyCharacter : public ACharacter{
    GENERATED_BODY()
public:
        //...
        UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
	UInputMappingContext* MyDefaultMappingContext;//输入映射

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
	UInputAction* MyLookAction;//代表动作
};

这两个属性后面要在蓝图中的详情面板中配置.

2.获取玩家的输入子系统添加输入映射

在函数SetupPlayerInputComponent下编写

1.获取玩家控制器


APlayerController* PlayController = Cast<APlayerController>(GetController());

2.获取输入子系统


auto SubSystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayController->GetLocalPlayer());

3.添加输入映射


SubSystem -> AddMappingContext(MyDefaultMappingContext,0);//单人玩家:0

3.注册鼠标动态监听

1.获取输入组件


UEnhancedInputComponent* InputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent);

2.绑定动作


InputComponent->BindAction(MyLookAction,ETriggerEvent::Triggered,this,&AMyCharacter::SetCameraRotation);

3.实现鼠标转动函数


//设置鼠标的移动
void AMyCharacter::SetCameraRotation(const FInputActionValue& Value)
{
	const auto Vector = Value.Get<FVector2d>();//获取鼠标的2d向量
	if(Controller != nullptr)
	{
		AddControllerYawInput(Vector.X);//偏航值
		AddControllerPitchInput(Vector.Y);
	}
	
}

完整的代码

AMyCharacter.h


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "InputAction.h"
#include "InputMappingContext.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/Character.h"
#include "GameFramework/SpringArmComponent.h"
#include "MyCharacter.generated.h"

struct FInputActionValue;

UCLASS()
class DEMO2_API AMyCharacter : public ACharacter
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	AMyCharacter();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UPROPERTY(VisibleAnywhere)
	UCameraComponent* MyCameraComponent;

	UPROPERTY(VisibleAnywhere)
	USpringArmComponent* MySpringArmComponent;


	

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// 调用将功能绑定到输入
	virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override;


	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
	UInputMappingContext* MyDefaultMappingContext;

	//左看右看,上看下看
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
	UInputAction* MyLookAction;
	//左右移动,上下移动
	UPROPERTY(EditAnywhere,BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
	UInputAction* MyMoveAction;
	// 设置鼠标的移动
	UFUNCTION(BlueprintCallable, Category="梁典典的函数",DisplayName="控制鼠标旋转")
	void SetCameraRotation(const FInputActionValue& Value);
	
	// 设置前进方向
	UFUNCTION(BlueprintCallable,Category="梁典典的函数",DisplayName="控制任务移动")
	void Move(const FInputActionValue& Value);

	//跳
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
	UInputAction* MyJumpAction;
};

AMyCharacter.cpp


// Fill out your copyright notice in the Description page of Project Settings.


#include "MyCharacter.h"

#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "GameFramework/CharacterMovementComponent.h"

// 设置默认值
AMyCharacter::AMyCharacter()
{
	// 设置此字符每帧调用 Tick()。  如果不需要,您可以将其关闭以提高性能。
	PrimaryActorTick.bCanEverTick = true;


	//创建摄像机杆子
	MySpringArmComponent = CreateDefaultSubobject<USpringArmComponent>(TEXT("LddSpringArmComponent"));
	MySpringArmComponent->bUsePawnControlRotation = true;//跟随角色旋转
	MySpringArmComponent->SetupAttachment(RootComponent);


	//创建摄像机
	MyCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("LddCameraComponent"));
	MyCameraComponent->SetupAttachment(MySpringArmComponent);//附加到杆子
	MyCameraComponent->SetRelativeLocation(FVector(0,0,50.f));
	MyCameraComponent->bUsePawnControlRotation = true;


	//让角色的朝向始终和当前的移动方向一致
	GetCharacterMovement()->bOrientRotationToMovement = true;

	//保证角色平滑的旋转
	bUseControllerRotationYaw = false;
	bUseControllerRotationPitch = false;
}

// 游戏开始或生成时调用
void AMyCharacter::BeginPlay()
{
	Super::BeginPlay();
}

// 调用每一帧
void AMyCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

// 调用将功能绑定到输入
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);


	//添加输入上下文映射
	if(APlayerController* PlayController = Cast<APlayerController>(GetController()))
	{
		if(auto SubSystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayController->GetLocalPlayer()))
		{
			SubSystem -> AddMappingContext(MyDefaultMappingContext,0);
		}
	}


	if (UEnhancedInputComponent* InputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
	{
		// Jumping
		InputComponent->BindAction(MyJumpAction, ETriggerEvent::Started, this, &ACharacter::Jump);
		InputComponent->BindAction(MyJumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
		InputComponent->BindAction(MyLookAction,ETriggerEvent::Triggered,this,&AMyCharacter::SetCameraRotation);
		InputComponent->BindAction(MyMoveAction,ETriggerEvent::Triggered,this,&AMyCharacter::Move);
	}

	UE_LOG(LogTemp,Log,TEXT("AMyCharacter::SetupPlayerInputComponent"));
}

//设置鼠标的移动
void AMyCharacter::SetCameraRotation(const FInputActionValue& Value)
{
	const auto Vector = Value.Get<FVector2d>();
	UE_LOG(LogTemp,Log,TEXT("AMyCharacter::SetCameraRotation:x:%.2f,y:%.2f"),Vector.X,Vector.Y);
	if(Controller != nullptr)
	{
		AddControllerYawInput(Vector.X);
		AddControllerPitchInput(Vector.Y);
	}
}

//让角色移动
void AMyCharacter::Move(const FInputActionValue& Value)
{
	const auto Vector = Value.Get<FVector2d>();
	if(Controller != nullptr)
	{
		//获取方向
		const FRotator Rotation =  Controller->GetControlRotation();

		//获取左右的方向
		const FRotator YawNewRotator = FRotator(0,Rotation.Yaw,0);
		const FRotationMatrix Matrix = FRotationMatrix(YawNewRotator);
		//获取向前的向量
		const FVector X = Matrix.GetUnitAxis(EAxis::X);
		//获取左右的向量
		const FVector Y = Matrix.GetUnitAxis(EAxis::Y);
		UE_LOG(LogTemp,Log,TEXT("角色移动:输入X:%.2f,输入Y:%.2f,保持左右的旋转角度:%.2f(不关心上下角度)"),Vector.X,Vector.Y,Rotation.Yaw);
		AddMovementInput(X,Vector.Y);
		AddMovementInput(Y,Vector.X);
	}
}

chatgpt

问题1:这些概念太难了,对我来说,很难很难

理解这些概念确实有点复杂,尤其是在你刚开始学习 Unreal Engine 的时候。不要担心,这是一个正常的过程,随着时间和练习,你会逐渐掌握它们。我们可以一起慢慢来,逐步简化这些概念,帮助你更好地理解。

我会试着用更简单的方式解释,看看是否能帮你更容易理解:

1. 输入向量(FVector2d

你可以把输入向量想象成一个手柄或键盘输入的方向。假设你在用手柄操作:

  • Vector.X 代表左右方向,值越大代表往右移动,越小代表往左移动。
  • Vector.Y 代表前后方向,值越大代表往前移动,越小代表往后移动。

所以这个 Vector 就是表示玩家的输入方向。

2. 控制器旋转

控制器的旋转简单来说,就是你角色朝向的方向。假设你在游戏里用鼠标或者右摇杆控制角色的视角旋转,这就是控制器的“旋转角度”。旋转分为:

  • Yaw:左右旋转(水平转头)。
  • Pitch:上下旋转(抬头或低头)。 在这个例子里,我们只关心角色左右转头的方向(Yaw),所以忽略了上下抬头的部分。

3. 前进和左右的方向

  • 前进方向:假设角色现在面对一个方向,这就是“前进方向”。前进方向对应着 X 轴。
  • 左右方向:想象一下,如果你站着不动,左右方向就是你的身体的两侧。这个方向对应着 Y 轴。

4. 移动逻辑

当你输入方向时:

  • Vector.Y 代表你是往前走还是往后退,程序就让你根据“前进方向”去移动。
  • Vector.X 代表你是往左移还是往右移,程序就让你根据“左右方向”去移动。

最终,这段代码就是让角色根据你输入的方向移动,无论你是用键盘、鼠标还是手柄。


你可以慢慢分步骤去理解这些代码,并用简单的例子去测试效果。每次理解一个小概念,尝试把它和实际操作联系起来,就会变得更容易。有什么具体的部分你想再深入理解的,或者需要更简单的解释,告诉我,我可以继续帮助你!

问题2FRotationMatrix这个是什么东西?

FRotationMatrix 是 Unreal Engine 中的一个类,用来表示旋转矩阵。旋转矩阵是数学中的一个工具,用来描述物体在三维空间中的旋转。虽然它在背后有复杂的数学原理,但我们可以用简单的方式来理解它在游戏开发中的用途。

简单解释

你可以把 FRotationMatrix 想象成一个工具,它可以根据给定的旋转角度(例如角色的朝向)生成一个矩阵,这个矩阵可以用来计算角色在这个旋转角度下的前进方向左右方向等信息。

具体怎么用?

在游戏中,角色不仅有位置,还会有方向(旋转角度)。当你让角色旋转后,你需要知道这个新的旋转角度下,角色的是哪边,又是哪边。

  • FRotationMatrix(YawNewRotator).GetUnitAxis(EAxis::X):获取角色朝向的前进方向()。
  • FRotationMatrix(YawNewRotator).GetUnitAxis(EAxis::Y):获取角色的左右方向(左或右)。

实例讲解

在你提供的代码中,FRotationMatrix 是根据角色当前的旋转角度创建的,然后用它来获取角色的“前进”和“左右”方向。这个过程相当于告诉程序:

  • 前进方向X 轴):角色现在面朝的方向。
  • 左右方向Y 轴):角色左右两边的方向。

为什么需要 FRotationMatrix

举个例子,如果角色面朝北方(0度),那么:

  • 前进方向就是正北(+X)。
  • 左右方向就是正东(+Y)。

但是如果角色转向了东边(90度),那么:

  • 前进方向变成了正东(+X)。
  • 左右方向变成了正南(+Y)。

你无法仅用一个简单的数字(角度)去描述这些复杂的方向变化,这时就需要通过 FRotationMatrix 来帮助计算这些方向。

核心理解

  • FRotationMatrix 是用来处理物体旋转方向的工具。
  • 它会根据一个旋转角度,告诉你在这个角度下的“前进”和“左右”方向。

进一步解释

在数学中,矩阵是一种表示数据的方式,可以用来执行各种操作(比如旋转、缩放等)。在三维空间里,物体的旋转可以通过一个 3x3 的矩阵来表示。FRotationMatrix 背后的数学细节涉及矩阵的运算和线性代数,但你只需要知道它帮你计算了方向,你就可以利用这些方向来让角色移动。


不需要深入理解复杂的数学,你只需要知道它是用来帮助你根据角色的朝向,计算出前、后、左、右的方向。如果你有更多问题,或者想看看具体的例子,我可以进一步解释!

参考文档

输入文档

返回顶部