UnrealEngine5 如何为 FPS 游戏设置角色

前言

FPS 是第一人称射击游戏的简称,从反恐精英开始,FPS 游戏已经成为了大热门游戏的首选,今天就让我带大家使用虚幻5(UnrealEngine5)来制作一款简单的FPS游戏吧!

准备

工程创建

打开我们 UE5 的编辑器,选择第一人称射击游戏,选择 C++,设置好您的工程名称,然后创建游戏,我的工程命名叫ROTD。

资源准备

虚幻5的安装我在这里就不铺开给大家演示了,大家可以自行去官方文档了解。 今天文章中所用到的 FPS 的资源均来自于在 Epic 商城,分别如下:

如果大家对这个资源感兴趣的话,可以联系我。

将下载好的资源放入工程的 Content 文件夹下,然后运行我们的工程。

角色蓝图

创建一个蓝图对象,然后继承自父类 ROTDCharacter,命名为 Henry_BP, 因为我给我的角色取名叫亨利,源自于我之前看过的一个电影硬核亨利,如图:

打开 Henry_BP,然后再选中 Viewport 窗口,为其添加 Skeletal Mesh, 我这里用到的骨骼网格体如图:

添加进去后,调整 Mesh 1P 和摄像机的位置如图:

这里的组件名称都是我们在C++代码中设置的名称,大家可以在 xxxCharacter.cpp 中看到:

.h 头文件

C++ 复制代码
	/** Pawn mesh: 1st person view (arms; seen only by self) */
	UPROPERTY(VisibleDefaultsOnly, Category=Mesh)
	USkeletalMeshComponent* Mesh1P;

	/** First person camera */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
	UCameraComponent* FirstPersonCameraComponent;

.cpp 文件

C++ 复制代码
AROTDCharacter::AROTDCharacter()
{
	// Set size for collision capsule
	GetCapsuleComponent()->InitCapsuleSize(55.f, 96.0f);

	// set our turn rates for input
	TurnRateGamepad = 45.f;

	// Create a CameraComponent	
	FirstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
	FirstPersonCameraComponent->SetupAttachment(GetCapsuleComponent());
	FirstPersonCameraComponent->SetRelativeLocation(FVector(-39.56f, 1.75f, 64.f)); // Position the camera
	FirstPersonCameraComponent->bUsePawnControlRotation = true;

	// Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)
	Mesh1P = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("CharacterMesh1P"));
	Mesh1P->SetOnlyOwnerSee(true);
	Mesh1P->SetupAttachment(FirstPersonCameraComponent);
	Mesh1P->bCastDynamicShadow = false;
	Mesh1P->CastShadow = false;
	Mesh1P->SetRelativeRotation(FRotator(1.9f, -19.19f, 5.2f));
	Mesh1P->SetRelativeLocation(FVector(-0.5f, -4.4f, -155.7f));

}

加上骨骼后,接下来就要给它添加动画了,接着往下看。

动画蓝图

创建一个动画蓝图,双击打开,为其添加三个 Bool 型的变量,如图:

分别代表当前是否在移动,是否跳跃,以及是否在奔跑。

随后,我们为其创建站立,走路奔跑以及跳跃的动画状态机,如图:

每个状态中都去关联对应的动画,这里关联的动画关键字为 Empty_Hand.

随后,打开 EventGraph 为其添加蓝图逻辑,如图所示:

这里解释一下:

1.通过 TryGetPawnOwner 节点获取 Pawn ,然后将其Cast为我们的蓝图对象 Henry_BP,这样我们才能获取它里面的值 2.GetVelocity节点的VectorLength可以判断角色是否在移动,如果 > 0, 就设置 IsMoving 为 true 3.同理,通过Character Movement 的 isFalling 值,可以判断玩家是否跳跃 4.IsRunning 是通过按住 Shift 键来判断是否设置为true 或 false

随后回到我们的角色蓝图中,为角色添加动画蓝图,如图:

角色的移动,也已经在C++代码中模板为我们补充好了,如下:

C++ 复制代码
void AROTDCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
	// Set up gameplay key bindings
	check(PlayerInputComponent);

	// Bind jump events
	PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
	PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);

	// Bind fire event
	PlayerInputComponent->BindAction("PrimaryAction", IE_Pressed, this, &AROTDCharacter::OnPrimaryAction);

	// Enable touchscreen input
	EnableTouchscreenMovement(PlayerInputComponent);

	// Bind movement events
	PlayerInputComponent->BindAxis("Move Forward / Backward", this, &AROTDCharacter::MoveForward);
	PlayerInputComponent->BindAxis("Move Right / Left", this, &AROTDCharacter::MoveRight);

	// We have 2 versions of the rotation bindings to handle different kinds of devices differently
	// "Mouse" versions handle devices that provide an absolute delta, such as a mouse.
	// "Gamepad" versions are for devices that we choose to treat as a rate of change, such as an analog joystick
	PlayerInputComponent->BindAxis("Turn Right / Left Mouse", this, &APawn::AddControllerYawInput);
	PlayerInputComponent->BindAxis("Look Up / Down Mouse", this, &APawn::AddControllerPitchInput);
	PlayerInputComponent->BindAxis("Turn Right / Left Gamepad", this, &AROTDCharacter::TurnAtRate);
	PlayerInputComponent->BindAxis("Look Up / Down Gamepad", this, &AROTDCharacter::LookUpAtRate);
}

void AROTDCharacter::MoveForward(float Value)
{
	if (Value != 0.0f)
	{
		// add movement in that direction
		AddMovementInput(GetActorForwardVector(), Value);
	}
}

void AROTDCharacter::MoveRight(float Value)
{
	if (Value != 0.0f)
	{
		// add movement in that direction
		AddMovementInput(GetActorRightVector(), Value);
	}
}

void AROTDCharacter::TurnAtRate(float Rate)
{
	// calculate delta for this frame from the rate information
	AddControllerYawInput(Rate * TurnRateGamepad * GetWorld()->GetDeltaSeconds());
}

void AROTDCharacter::LookUpAtRate(float Rate)
{
	// calculate delta for this frame from the rate information
	AddControllerPitchInput(Rate * TurnRateGamepad * GetWorld()->GetDeltaSeconds());
}

结尾

为 FPS 游戏设置角色就完成了,运行我们的编辑器,就可以通过 W A S D 键以及空格键来操作角色了。

相关推荐
Clarify5 天前
一种增量式的状态同步方案
后端·游戏开发
foenix668 天前
Unreal的Audio::IAudioCaptureStream在Android中录制数据异常
android·c#·unreal engine
异次元的归来8 天前
UE5的TRS矩阵
线性代数·矩阵·ue5·游戏引擎·unreal engine
Thomas_YXQ11 天前
Unity3D项目为什么要使用FairyGUI
开发语言·unity·游戏引擎·unity3d·游戏开发
DoomGT14 天前
Design - 个人设计的一些科幻场景
游戏引擎·虚幻·虚幻引擎·unreal engine
Raysen15 天前
GridLayout玩出花系列-使用Android原生GridLayout控件打造方块消除小游戏
android·游戏开发
Amd79423 天前
Nuxt.js 应用中的 render:island 事件钩子
服务器·渲染·客户端·nuxt·seo·钩子·动态
kissSimple23 天前
给UE5优化一丢丢编辑器性能
ue5·虚幻引擎·unreal engine·unreal engine 5
MavenTalk23 天前
Mac 环境下类Xshell 的客户端介绍
macos·xshell·客户端·iterm2·termius
Thomas_YXQ25 天前
Unity3D ngui和ugui区别与优缺点详解
服务器·游戏·unity·unity3d·游戏开发