9. UE5 RPG创建UI(下)

这篇具有很好参考价值的文章主要介绍了9. UE5 RPG创建UI(下)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在上一篇文章里,制作了显示血量和蓝量的ui,并且还将ui和获取数据使用的控制器层创建出来并初始化成功。现在只有主用户控件上面被添加了控制器层,还未给每个用户控件赋予控制器层。接下来要实现对属性的广播功能,在属性值变化的时候,能够在蓝图中获取到数值的变化并更新到用户控件上面。

使用广播设置初始值

首先在控制器层里面添加一个函数

virtual void BroadcastInitialValues();

这个函数用于广播初始化函数。我们上一文章里基于控制器层类创建了一个子类,专门用于Overlay的,在里面复写这个函数

public:
	virtual void BroadcastInitialValues() override;

接下来就是重点,我们将以委托的形式设置每个属性的广播功能,这里就需要用到委托对应的函数。不清楚的小伙伴可以看下这里
一文理解透UE委托Delegate

这里使用了动态多播委托函数绑定,下面是实现,委托的函数DelegateName 首字母必须以F开头。
一下是定义了获取血量的委托,返回一个参数就是当前的血量浮点数。

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHealthChangedSignature,float, NewHealth);

接下来定义一个变量,实现对回调的引用

	UPROPERTY(BlueprintAssignable, Category="GAS|Attributes")
	FOnHealthChangedSignature FOnHealthChanged;

然后最后通过广播形式将数据广播出去

FOnHealthChanged.Broadcast(50.f);

当前,我们需要实际的血量数值,所以广播出去的就是从AttributeSet里面获取到的值

	const UAttributeSetBase* AttributeSetBase = CastChecked<UAttributeSetBase>(AttributeSet);

	OnHealthChanged.Broadcast(AttributeSetBase->GetHealth());
	OnMaxHealthChanged.Broadcast(AttributeSetBase->GetMaxHealth());

函数有了,需要有个地方调用,实例化这个函数我们是在HUD类里面实例化的,那就在实例化完成后面调用。也就是MyHUD.cpp里面的InitOverlay()里面,这个顺序不能错,首先需要设置控制器层,这时会触发蓝图里面可以调用的设置控制器层回调通知,用户控件会以此来绑定广播回调。然后再广播初始的值,用户控件里就实现了对值的初始化设置。

	OverlayWidgetController = GetOverlayWidgetController(WidgetControllerParams); //获取控制器层

	OverlayWidget->SetWidgetController(OverlayWidgetController); //设置用户控件的控制器层
	OverlayWidgetController->BroadcastInitialValues(); //初始化广播

这样设置完成以后,打开UE,在设置的WBP_Overlay里面,在上一章最后设置的设置完成控制器层对象后的回调中,将控制器层对象传递给需要显示的用户控件节点。
9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui
做到这一步,我们在需要同步数据的UI上面就都可以获取到控制器层对象。接着,我们要将Overlay的控制器层类公开给蓝图。

UCLASS(BlueprintType, Blueprintable)
class AURA_API UOverlayWidgetController : public UMyWidgetController

直接在类上面的UCLASS()内添加上两个参数。
BlueprintType 将此类公开为可用于蓝图中的变量的类型。
Blueprintable 将此类公开为用于创建蓝图的可接受基类。默认为NotBlueprintable,除非继承时就并非如此。此说明符由子类继承。
设置完成这两项,我们就可以把控制器层对象转换为控制器层类的实例了。
为了方便后面的工作,推荐不要直接使用c++的类,通过蓝图创建一个c++的基类去使用。

9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui
将HUD里面的控制器层类的引用修改成蓝图的。
9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui
在进度条的蓝图基类WBP_GlobeProgressBar中添加一个函数,用于设置进度条百分比,接收一个参数
9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui
之前在OverlayWidget里面,将在c++里面生成的控制器层对象传递给了对应的用户组件。我们在血量控件中,也可以使用WidgetControllerSet通知,获得通知后将变量保存。
9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui
之前我们在OverlayWidgetController里面添加了对血量和最大血量的广播,所以,在蓝图里,我们可以实现绑定血量变化。在数值变化后,可以通过调用设置进度条百分比进行进度条设置。
9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui
顺便也绑定最大血量。
9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui

监听数值的变化

上面我们实现通过广播的形式对用户控件内的值进行初始化,还未实现对数值变化后触发广播更新ui显示。
我们需要通过使用AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate()来注册一个监听一个值的变化,如果监听的数值变化了接着将变化后的数值进行广播。比如下面就是监听血量属性是否变化

AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AttributeSetBase->GetHealthAttribute())

为了区分开,我们需要在控制器层类里面新加一个函数,专门用来注册监听数据变化回调的。

virtual void BindCallbacksToDependencies() override;

接着创建两个保护类型的函数,用于监听到数值变化后的回调函数

protected:
	void HealthChanged(const FOnAttributeChangeData& Data) const;
	void MaxHealthChanged(const FOnAttributeChangeData& Data) const;

接着,在绑定监听函数内实现监听:

void UOverlayWidgetController::BindCallbacksToDependencies()
{
	const UAttributeSetBase* AttributeSetBase = CastChecked<UAttributeSetBase>(AttributeSet);

	AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
		AttributeSetBase->GetHealthAttribute()).AddUObject(this, &UOverlayWidgetController::HealthChanged);

	AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
		AttributeSetBase->GetMaxHealthAttribute()).AddUObject(this, &UOverlayWidgetController::MaxHealthChanged);
	
}

在数值变化时,就会触发去调用Changed函数,我们只需要在changed函数内,将数值广播给蓝图即可。

void UOverlayWidgetController::HealthChanged(const FOnAttributeChangeData& Data) const
{
	OnHealthChanged.Broadcast(Data.NewValue);
}

void UOverlayWidgetController::MaxHealthChanged(const FOnAttributeChangeData& Data) const
{
	OnMaxHealthChanged.Broadcast(Data.NewValue);
}

最后,需要找一个地方调用监听函数绑定,我选在了HUD对初始化数值调用之后

	OverlayWidget->SetWidgetController(OverlayWidgetController); //设置用户控件的控制器层
	OverlayWidgetController->BroadcastInitialValues(); //初始化广播的值
	OverlayWidgetController->BindCallbacksToDependencies(); //绑定监听数值变化

接下来,按照之前的方式将蓝的设置添加上,这里不在编写实现,因为和血量的方式一行按照上面一步步来即可。下面列一下代码。

控制器层代码

MyWidgetController.h

// 版权归暮志未晚所有。

#pragma once

#include "CoreMinimal.h"
#include "AbilitySystemComponent.h"
#include "UObject/NoExportTypes.h"
#include "MyWidgetController.generated.h"

class UAttributeSet;
class UAbilitySystemComponent;

/**
 * 生成用户控件控制器的结构体,需要四项内容去生成。
 */
USTRUCT(BlueprintType)
struct FWidgetControllerParams
{
	GENERATED_BODY()
	FWidgetControllerParams(){}
	FWidgetControllerParams(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS)
	: PlayerController(PC),
	PlayerState(PS),
	AbilitySystemComponent(ASC),
	AttributeSet(AS)
	{}

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TObjectPtr<APlayerController> PlayerController = nullptr;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TObjectPtr<APlayerState> PlayerState = nullptr;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent = nullptr;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TObjectPtr<UAttributeSet> AttributeSet = nullptr;
};

/**
 * 用户控件控制器层,用户控件可从控制器层更新数据显示,以及为控制器层提供输入。
 */
UCLASS()
class AURA_API UMyWidgetController : public UObject
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable)
	void SetWidgetControllerParams(const FWidgetControllerParams& WCParams);
	virtual void BroadcastInitialValues(); //广播初始化的值
	virtual void BindCallbacksToDependencies(); //绑定数值变动后回调的广播

protected:

	UPROPERTY(BlueprintReadOnly, Category="WidgetController")
	TObjectPtr<APlayerController> PlayerController;

	UPROPERTY(BlueprintReadOnly, Category="WidgetController")
	TObjectPtr<APlayerState> PlayerState;

	UPROPERTY(BlueprintReadOnly, Category="WidgetController")
	TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;

	UPROPERTY(BlueprintReadOnly, Category="WidgetController")
	TObjectPtr<UAttributeSet> AttributeSet;
	
};

MyWidgetController.cpp

// 版权归暮志未晚所有。


#include "UI/WidgetController/MyWidgetController.h"

void UMyWidgetController::SetWidgetControllerParams(const FWidgetControllerParams& WCParams)
{
	PlayerController = WCParams.PlayerController;
	PlayerState = WCParams.PlayerState;
	AbilitySystemComponent = WCParams.AbilitySystemComponent;
	AttributeSet = WCParams.AttributeSet;
}

void UMyWidgetController::BroadcastInitialValues()
{
}

void UMyWidgetController::BindCallbacksToDependencies()
{
}

OverlayWidgetController.h

// 版权归暮志未晚所有。

#pragma once

#include "CoreMinimal.h"
#include "UI/WidgetController/MyWidgetController.h"
#include "OverlayWidgetController.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHealthChangedSignature,float, NewHealth);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMaxHealthChangedSignature,float, NewMaxHealth);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnManaChangedSignature,float, NewMana);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMaxManaChangedSignature,float, NewMaxMana);

/**
 * 屏幕覆盖用户控件控制器层基类,继承与用户控件控制器
 */
UCLASS(BlueprintType, Blueprintable)
class AURA_API UOverlayWidgetController : public UMyWidgetController
{
	GENERATED_BODY()

public:
	virtual void BroadcastInitialValues() override;
	virtual void BindCallbacksToDependencies() override;

	UPROPERTY(BlueprintAssignable, Category="GAS|Attributes")
	FOnHealthChangedSignature OnHealthChanged;

	UPROPERTY(BlueprintAssignable, Category="GAS|Attributes")
	FOnMaxHealthChangedSignature OnMaxHealthChanged;

	UPROPERTY(BlueprintAssignable, Category="GAS|Attributes")
	FOnManaChangedSignature OnManaChanged;

	UPROPERTY(BlueprintAssignable, Category="GAS|Attributes")
	FOnMaxManaChangedSignature OnMaxManaChanged;

protected:
	void HealthChanged(const FOnAttributeChangeData& Data) const;
	void MaxHealthChanged(const FOnAttributeChangeData& Data) const;
	void ManaChanged(const FOnAttributeChangeData& Data) const;
	void MaxManaChanged(const FOnAttributeChangeData& Data) const;
};

OverlayWidgetController.cpp

// 版权归暮志未晚所有。


#include "UI/WidgetController/OverlayWidgetController.h"

#include "AbilitySystem/AttributeSetBase.h"

void UOverlayWidgetController::BroadcastInitialValues()
{
	const UAttributeSetBase* AttributeSetBase = CastChecked<UAttributeSetBase>(AttributeSet);

	OnHealthChanged.Broadcast(AttributeSetBase->GetHealth());
	OnMaxHealthChanged.Broadcast(AttributeSetBase->GetMaxHealth());
	OnManaChanged.Broadcast(AttributeSetBase->GetMana());
	OnMaxManaChanged.Broadcast(AttributeSetBase->GetMaxMana());
}

void UOverlayWidgetController::BindCallbacksToDependencies()
{
	const UAttributeSetBase* AttributeSetBase = CastChecked<UAttributeSetBase>(AttributeSet);

	AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
		AttributeSetBase->GetHealthAttribute()).AddUObject(this, &UOverlayWidgetController::HealthChanged);

	AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
	AttributeSetBase->GetMaxHealthAttribute()).AddUObject(this, &UOverlayWidgetController::MaxHealthChanged);

	AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
		AttributeSetBase->GetManaAttribute()).AddUObject(this, &UOverlayWidgetController::ManaChanged);

	AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
		AttributeSetBase->GetMaxManaAttribute()).AddUObject(this, &UOverlayWidgetController::MaxManaChanged);
	
}

void UOverlayWidgetController::HealthChanged(const FOnAttributeChangeData& Data) const
{
	OnHealthChanged.Broadcast(Data.NewValue);
}

void UOverlayWidgetController::MaxHealthChanged(const FOnAttributeChangeData& Data) const
{
	OnMaxHealthChanged.Broadcast(Data.NewValue);
}

void UOverlayWidgetController::ManaChanged(const FOnAttributeChangeData& Data) const
{
	OnManaChanged.Broadcast(Data.NewValue);
}

void UOverlayWidgetController::MaxManaChanged(const FOnAttributeChangeData& Data) const
{
	OnMaxManaChanged.Broadcast(Data.NewValue);
}



多人模式调试UI显示

在运行下拉中,将人数修改为2
9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui
然后将客户端同时作为服务器使用
9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui
接着会发现运行了两个实例,并且拥有相同的血量和蓝量
9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui
接下来,控制一个角色去吃掉药瓶,会发现她的血和蓝都产生了变化,而另外一个没有变化
9. UE5 RPG创建UI(下),UE5 RPG,unreal,ue5,ui
到这里功能实现了。文章来源地址https://www.toymoban.com/news/detail-820855.html

到了这里,关于9. UE5 RPG创建UI(下)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 6. UE5 RPG AttributeSet的设置

    AttributeSet 负责定义和持有属性并且管理属性的变化。开发者可以子类化UAttributeSet。在OwnerActor的构造方法中创建的AttributeSet将会自动注册到ASC。这一步必须在C++中完成。 Attributes 是由 FGameplayAttributeData定义的浮点值。 Attributes能够表达从角色的生命值到角色等级到药瓶的价格等

    2024年01月18日
    浏览(26)
  • (UE4/UE5)Unreal Engine中使用HLOD

    本教程将详细介绍在Unreal Engine的不同版本(4.20-4.24、4.25-4.26、5.2)中如何使用Hierarchical Level of Detail (HLOD)。注意,每个版本中使用HLOD的方法可能会有所不同。 步骤一:预先生成LOD打开UE4.21,点击Content Browser(内容浏览器)中你想要生成LOD的静态网格。 步骤二:在静态网格编

    2024年02月10日
    浏览(34)
  • 7. UE5 RPG修改GAS的Attribute的值

    前面几节文章介绍了如何在角色身上添加AbilitySystemComponent和AttributeSet。并且还实现了给AttributeSet添加自定义属性。接下来,实现一下如何去修改角色身上的Attribute的值。 首先创建一个继承于Actor的c++类,actor是可以放置到场景中的基类。 创建一个静态模型组件,用来显示当前

    2024年01月18日
    浏览(30)
  • 14. UE5 RPG使用曲线表格设置回复血量值

    之前的文章中,我使用的都是固定的数值来设置血量回复或者蓝量回复,在这篇文章里面,介绍一下使用曲线表格。通过曲线表格我们可以设置多个数值,然后通过去通过修改索引对应的数值去修改回复的血量或者蓝量。 首先创建一个曲线表格,在其它里面找到 然后可以根

    2024年02月21日
    浏览(31)
  • UE5【UMG】 - Simple Menu UI v3 学习笔记

    案例地址:https://www.unrealengine.com/marketplace/zh-CN/product/simple-menu-ui 这个Demo简单,基本结构都有,可以用来入手学习 1) 先查看 Project-MapsModes,找到默认启动Map、GameMode与GameInstance;此外,Input设置也需要看下。 2)当UE5程序启动时,默认启动GameInstance、GameMode与默认Map; 接着,

    2024年02月06日
    浏览(35)
  • UE5 虚幻引擎中UI、HUD和UMG的区别与联系

    🙋‍♂️ 作者:海码007 📜 专栏:UE虚幻引擎专栏 💥 标题:UE5 虚幻引擎中UI、HUD和UMG的区别与联系 ❣️ 寄语:加油,一次专注一件事! 🎈 最后: 文章作者技术和水平有限,如果文中出现错误,希望大家能指正,同时有问题的话,欢迎大家留言讨论。 💥在学习虚幻引擎

    2024年01月20日
    浏览(30)
  • Unreal Engine(UE5)中构建离线地图服务

    1.     首先需要用到3个软件,Unreal Engine,gis office 和 bigemap离线服务器 Unreal Engine下载地址:点击前往下载页面 Gis office下载地址:点击前往下载页面 Bigemap离线服务器 下载地址: 点击前往下载页面 Unreal Engine用于数字孪生项目开发,gis office是一款地理信息软件,可用于获取

    2024年01月18日
    浏览(34)
  • UE4,UE5虚幻引擎,怎么在蓝图中获取FPS帧速率,显示在UMG(UI)上

    前言:在UE中可以使用命令行比如stat fps显示帧率,但只是显示在界面,假设我们要在蓝图中获取FPS帧率,并且显示在我们创建的UMG控件蓝图。这种stat fps命令行的形式就不行了,因为它只会固定显示在右上角的位置。 1、在Tick中获取DeltaSeconds,用1除InDeltaTime,得到帧速率。

    2024年02月11日
    浏览(36)
  • 【UE5 Cesium】15-Cesium for Unreal 加载本地影像和地形

    目录 一、加载全球无高度地形 二、加载区域DEM 三、加载离线地图影像 1. 先去如下网址下载全球无高度地形:Using a global terrain layer without height detail - #9 by RidhwanAziz - Cesium for Unreal - Cesium Community 下载后如下: 解压后可以看到是一个.tif格式的文件 2. 打开CesiumLab,需要将tif转为

    2024年02月07日
    浏览(30)
  • 【UE5】蓝图UI控件菜单锚(Menu Anchor)的使用与浮动详情窗口的制作

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 最近在做毕设,一直在苦恼要怎么精准地把浮动的详情窗口放在图标的一边,就比如下图中的效果 本来也有想过直接获取控件在屏幕上的位置来计算浮动窗口的生成位置,但神奇的是蓝图似乎没有这个

    2024年02月11日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包