UE5 游戏模板 —— TopDownGame 俯视角游戏

UE5 游戏模板 ------ TopDownGame 俯视角游戏

前言

上一篇文章介绍了一下PuzzleGame模板的流程,我们循序渐进这次介绍TopDownGame。

实际上TopDownGame和之前的PuzzleGame非常类似都是俯视角都要使用射线检测去做相应的判定。但是TopDownGame提供了角色寻路和角色位移的方式。


一、模块导入

UE是以导入模块来构建项目的,我们可以自己定义插件等内容当作一个模块来进行导入。

可以看到下图中导入了很多的模块

其中 "Core", "CoreUObject", "Engine", "InputCore" 是常用的也是默认都会导入的几个模块,有着最基础的内容。

"AIModule" 这个是用作寻路的必要模块

"Niagara" 粒子系统相关的模块

"EnhancedInput" 新的输入系统模块

二、TopDownGameMode

我们在之前的PuzzleGame中就有讲解过,下面的方式可以指定C++的蓝图派生类

三、TopDownPlayerController

1、构造函数

还是和上一节的内容相似,都是显示鼠标和设置鼠标的默认类型。
CachedDestination 用于记录点击到的点
FollowTime 用于记录鼠标按住的时间

2、SetupInputComponent

初始化新输入系统

获取新输入的本地玩家子系统,对子系统设置MappingContext

cpp 复制代码
	// Add Input Mapping Context
	if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
	{
		Subsystem->AddMappingContext(DefaultMappingContext, 0);
	}

将InputComponent 转换成新输入组件并绑定事件

cpp 复制代码
// Set up action bindings
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(InputComponent))
{
	// Setup mouse input events
	EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Started, this, &ATestTopDownPlayerController::OnInputStarted);
	EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Triggered, this, &ATestTopDownPlayerController::OnSetDestinationTriggered);
	EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Completed, this, &ATestTopDownPlayerController::OnSetDestinationReleased);
	EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Canceled, this, &ATestTopDownPlayerController::OnSetDestinationReleased);

	// Setup touch input events
	EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Started, this, &ATestTopDownPlayerController::OnInputStarted);
	EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Triggered, this, &ATestTopDownPlayerController::OnTouchTriggered);
	EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Completed, this, &ATestTopDownPlayerController::OnTouchReleased);
	EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Canceled, this, &ATestTopDownPlayerController::OnTouchReleased);
}

处理输入逻辑

点击鼠标左键开始时先停止角色移动

cpp 复制代码
void ATestTopDownPlayerController::OnInputStarted()
{
	StopMovement();
}

按住触发鼠标左键

1.先累加帧时间间隔

2.发射射线(可能会疑问这个发射射线的方法,其实是对之前PuzzleGame中发射射线方法的一个封装下面详细讲解一下这个地方)

3.记录射线碰撞的点

4.计算移动的方向向量

cpp 复制代码
void ATestTopDownPlayerController::OnSetDestinationTriggered()
{
	// We flag that the input is being pressed
	FollowTime += GetWorld()->GetDeltaSeconds();
	
	// We look for the location in the world where the player has pressed the input
	FHitResult Hit;
	bool bHitSuccessful = false;
	if (bIsTouch)
	{
		bHitSuccessful = GetHitResultUnderFinger(ETouchIndex::Touch1, ECollisionChannel::ECC_Visibility, true, Hit);
	}
	else
	{
		bHitSuccessful = GetHitResultUnderCursor(ECollisionChannel::ECC_Visibility, true, Hit);
	}

	// If we hit a surface, cache the location
	if (bHitSuccessful)
	{
		CachedDestination = Hit.Location;
	}
	
	// Move towards mouse pointer or touch
	APawn* ControlledPawn = GetPawn();
	if (ControlledPawn != nullptr)
	{
		FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();
		ControlledPawn->AddMovementInput(WorldDirection, 1.0, false);
	}
}

松开鼠标左键

如果按键按下的时长小于设定值判定是鼠标瞬间点击,将玩家使用导航移动到目标点,同时播放粒子特效和声音

cpp 复制代码
void ATestTopDownPlayerController::OnSetDestinationReleased()
{
	// If it was a short press
	if (FollowTime <= ShortPressThreshold)
	{
		// We move there and spawn some particles
		UAIBlueprintHelperLibrary::SimpleMoveToLocation(this, CachedDestination);
		UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, FXCursor, CachedDestination, FRotator::ZeroRotator, FVector(1.f, 1.f, 1.f), true, true, ENCPoolMethod::None, true);

		if (AudioSound != nullptr)
		{
			UGameplayStatics::PlaySoundAtLocation(GetWorld(), AudioSound, CachedDestination);
		}
	}

	FollowTime = 0.f;
}

四、TopDownCharacter

初始化相机和相机臂

五、射线检测

我们已经遇到了多次射线检测让我们来仔细看一下

首先无论是哪种射线检测函数本质上是从一个点到另一个点的连线在此连线的路径上是否有物体遮挡碰撞。

1.我们要先获取到鼠标在屏幕上面的坐标

2.将屏幕上的坐标转换为世界中的坐标,可以想象是摄像机的那个投影面的位置

3.需要知道方向,其实就是摄像机看向的方向

4.确定终点,起点+方向*长度

5.传递需要碰撞的参数,调用LineTraceSingleByChannel

在PuzzleGame中我们曾用过这个函数,获取到了世界的位置和方向,实际上就是获取屏幕鼠标位置让后通过矩阵转换得到最终的值

我们现在在来看一下TopDownGame的射线检测


其实本质的原理都是一样的


总结

以上就是今天要讲的内容,自此两个典型的俯视角游戏就介绍到这里,接下来是第一人称和第三人称射击游戏的模板。

相关推荐
呆呆敲代码的小Y2 小时前
【Unity工具篇】| 超实用工具LuBan,快速上手使用
游戏·unity·游戏引擎·unity插件·luban·免费游戏·游戏配置表
我的offer在哪里3 小时前
用 Unity 从 0 做一个「可以玩的」游戏,需要哪些步骤和流程
游戏·unity·游戏引擎
串流游戏联盟3 小时前
启程!手机也能邂逅暖暖万相奇观
游戏·远程工作
User_芊芊君子4 小时前
HCCL高性能通信库编程指南:构建多卡并行训练系统
人工智能·游戏·ai·agent·测评
AI视觉网奇6 小时前
3d数字人 ue blender 绑定衣服对齐 2026
学习·ue5
前端不太难7 小时前
HarmonyOS 游戏里,Ability 是如何被重建的
游戏·状态模式·harmonyos
灵狐数据FoxData9 小时前
QQ农场今日回归,我们想“偷”回的到底是什么?
游戏·社交电子·业界资讯·娱乐·玩游戏
微祎_9 小时前
Flutter for OpenHarmony:构建一个 Flutter 平衡球游戏,深入解析动画控制器、实时物理模拟与手势驱动交互
flutter·游戏·交互
renke336411 小时前
Flutter for OpenHarmony:构建一个 Flutter 色彩调和师游戏,RGB 空间探索、感知色差计算与视觉认知训练的工程实现
flutter·游戏
ujainu13 小时前
Flutter + OpenHarmony 实现经典打砖块游戏开发实战—— 物理反弹、碰撞检测与关卡系统
flutter·游戏·openharmony·arkanoid·breakout