UE4 C++简易背包系统(上)
Posted Vincent_0000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UE4 C++简易背包系统(上)相关的知识,希望对你有一定的参考价值。
前言
本篇将告诉你如何初步创建背包系统。
初步效果图如下:
中间有个点,我们移动人物,当这个点移动到我们可以拾取的物体的时候,会显示他的名字。
前期操作
创建C++第三人称的项目。
创建三个文件夹,Blueprint
、Data
、UI
。方便之后操作。
交互物体基类实现
新建一个继承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++复刻AdvancedLocomotionSystemV动画高级系统---更新中
[工作积累] UE4 并行渲染的同步 - Sync between FParallelCommandListSet & FRHICommandListImmediate calls(代码片段