UE4 C++简易背包系统(上)

Posted Vincent_0000

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UE4 C++简易背包系统(上)相关的知识,希望对你有一定的参考价值。

前言

本篇将告诉你如何初步创建背包系统。

初步效果图如下:
中间有个点,我们移动人物,当这个点移动到我们可以拾取的物体的时候,会显示他的名字。


前期操作

创建C++第三人称的项目。

创建三个文件夹,BlueprintDataUI。方便之后操作。

交互物体基类实现

新建一个继承Actor的C++文件,命名为:Interactable(为了之后好理解,这里就先给一个例名。)

.h文件

  • 添加一个当玩家与可交互对象进行交互时调用的函数, 这个函数被标记为BlueprintImplementable,以便设计人员可以实现他们在蓝图中想要的任何定制功能。
UFUNCTION(BlueprintImplementableEvent)
	void Interact(APlayerController* controller);
  • 声明名字和属性(基类Interactable、后面会继承它的pickup等类名)
UPROPERTY(EditDefaultsOnly)
	FString Name;
	
UPROPERTY(EditDefaultsOnly)
	FString _Action;
  • 声明返回自己信息的函数,这个信息就是我们图片上面看到的一串英文。
UFUNCTION(BlueprintCallable, Category = "Pickup")
	FString GetUseText() const{ return FString::Printf(TEXT("%s : Press E to %s"), *Name, *_Action);}

注意:这里加了一个const, 和没加在蓝图中是有区别的。
这里是加上了const

没加const:

那么调用它就得要有东西连接他的那个引脚才行。

加上了会比没加上好一些,因为只要有人用到他返回的值了,那么这个函数就会被调用,相对来说在蓝图中需要连的东西比后者少。

.cpp文件

  • 构造函数,将变量信息初始化
Name = "Name not set";
_Action = "Interact";

拾取类函数实现

创建一个继承Interactable的C++文件,命名为:pickup

.h文件

声明构造函数,静态网格组件。

public:

	Apickup();

protected:

	UPROPERTY(EditAnywhere)
		UStaticMeshComponent* PickupMesh;

.cpp 文件

  • 构造函数
PickupMesh = CreateDefaultSubobject<UStaticMeshComponent>("PickupMesh");

将信息初始化。

玩家控制器类实现

新建一个继承PlayerController的C++文件,命名为:GameplayController

.h文件

添加一个储存交互类的变量。

public:
	//玩家当前所看到的交互性。如果玩家没有看到可交互的内容,那么这个值就等于nullptr。
	UPROPERTY(BlueprintReadWrite, VisibleAnywhere)
		class AInteractable* CurrentInteractable;

下面看如何去设置这个变量:

角色类函数处理

打开我们C++ 文件中的角色类

.h 文件

  • 射线拾取函数声明,待会会解释
protected:
	void CheckForInteractables();
  • 每一帧都要进行射线拾取函数的检测,所以要重写Tick函数。
public:
	virtual void Tick(float DeltaTime) override;

.cpp 文件

  • CheckForInteractables()

添加头文件:

#include "GameplayController.h"
#include "Interactable.h"

这个函数的整体思路就是通过调用LineTraceSingleByChannel,从StartTrace点开始到EndTrace点形成的一个射线中检测是否有接触到设置为可见的、符合QueryParams碰撞信息的对象,对象信息储存在HitResult中。如果有,通过这个碰撞结果去获取对象,判断是否为可交互的对象,如果是的,那么就将玩家控制器中的待拾取物体设置为当前这个物体。

// 射线拾取
FHitResult HitResult; // 存储碰撞的结果的变量

FVector StartTrace = FollowCamera->GetComponentLocation(); // 射线起始点
FVector EndTrace = (FollowCamera->GetForwardVector() * 300) + StartTrace; // 射线终止点。

FCollisionQueryParams QueryParams; // 储存了碰撞相关的信息
QueryParams.AddIgnoredActor(this); // 将我们角色自身忽略掉,减少性能开销

AGameplayController* controller = Cast<AGameplayController>(GetController()); // 玩家控制器

if (GetWorld()->LineTraceSingleByChannel(HitResult, StartTrace, EndTrace, ECC_Visibility, QueryParams) && controller) {
	//检查我们点击的项目是否是一个可交互的项目
	if (AInteractable* Interactable = Cast<AInteractable>(HitResult.GetActor())) {
		controller->CurrentInteractable = Interactable;
		return;
	}
}

//如果我们没有击中任何东西,或者我们击中的东西不是一个可交互的,设置currentinteractable为nullptr
controller->CurrentInteractable = nullptr;

创建UI

在UI中右击,然后点击↓

命名为:WB_Ingame
界面这么画:

文本内容点击图片之后在细节面板中的Content中。
点放在正中央,方便我们调试。
层级关系为:

点击第一个文本,然后创建绑定。

在蓝图中这么画:

这里的作用就是通过访问控制器中的GetUseText()来对文本中的内容进行修改。

创建蓝图

把项目给我们的第三人称角色的那个镜头向左移动100,。

创建继承GameplayController的蓝图命名为:BP_GameplayController

创建继承GameplayGameMode的蓝图命名为:BP_GameplayGameMode
在细节面板中修改属性:

创建继承pickup的蓝图命名为:BP_pickup。在细节面板中修改Name_Action属性。

打开项目设置,设置成下面这样:

后面就是这个功能的收尾动作了,比较简单就没有讲很细,编译运行就可以达到我那个效果啦!

以上是关于UE4 C++简易背包系统(上)的主要内容,如果未能解决你的问题,请参考以下文章

Unity UGUI有趣应用 -------------------- 背包系统(上)之简易单页背包系统及检索功能的实现

UE4蓝图与C++交互——射击游戏中多武器系统的实现

UE4 C++复刻AdvancedLocomotionSystemV动画高级系统---更新中

UE4 C++第三人称人物创建的基本代码(上)

[工作积累] UE4 并行渲染的同步 - Sync between FParallelCommandListSet & FRHICommandListImmediate calls(代码片段

UE4中使用蓝图实现简易的游戏暂停功能