UE5多人MOBA+GAS 8、制作头部血条


1、创建头部血条

添加一个cpp类继承UserWidget,命名为OverHeadStatsGauge
在这里插入图片描述
在这里插入图片描述
添加血条和蓝条,以及绑定回调用的函数

// 幻雨喜欢小猫咪

#pragma once

#include "CoreMinimal.h"
#include "ValueGauge.h"
#include "Blueprint/UserWidget.h"
#include "OverHeadStatsGauge.generated.h"

/**
 * 
 */
UCLASS()
class UOverHeadStatsGauge : public UUserWidget
{
	GENERATED_BODY()
public:
	void ConfigureWithASC(class UAbilitySystemComponent* AbilitySystemComponent);
private:
	UPROPERTY(meta = (BindWidget))
	TObjectPtr<UValueGauge> HealthBar;
	UPROPERTY(meta = (BindWidget))
	TObjectPtr<UValueGauge> ManaBar;
};
// 幻雨喜欢小猫咪


#include "UI/Gameplay/OverHeadStatsGauge.h"

#include "GAS/CAttributeSet.h"

void UOverHeadStatsGauge::ConfigureWithASC(UAbilitySystemComponent* AbilitySystemComponent)
{
	if (AbilitySystemComponent)
	{
		HealthBar->SetAndBoundToGameplayAttribute(AbilitySystemComponent, UCAttributeSet::GetHealthAttribute(), UCAttributeSet::GetMaxHealthAttribute());
		ManaBar->SetAndBoundToGameplayAttribute(AbilitySystemComponent, UCAttributeSet::GetManaAttribute(), UCAttributeSet::GetMaxManaAttribute());
	}
}

随后在引擎继承该类创建蓝图WBP_OverHeadStatsGauge
在这里插入图片描述

2、装载到角色上

CCharacter中添加UI组件以及初始化函数,像血条这种东西我们就不用在自己头上亮血条了,还需要一个判断角色是否由本地玩家控制

	// 客户端中初始化
	void ClientSideInit();
	/*放这里*/
	// 判断该角色是否由本地玩家控制
	bool IsLocallyControlledByPlayer() const;
#pragma region UI
private:
	// 头顶UI
	UPROPERTY(VisibleDefaultsOnly, Category = "UI")
	TObjectPtr<UWidgetComponent> OverHeadWidgetComponent;
	void ConfigureOverHeadStatusWidget();
#pragma endregion

构造函数中添加如下,并对ConfigureOverHeadStatusWidget函数进行实现,在开始游戏的时候调用该函数:

ACCharacter::ACCharacter()
{
	OverHeadWidgetComponent = CreateDefaultSubobject<UWidgetComponent>(TEXT("OverHeadWidgetComponent"));
	OverHeadWidgetComponent->SetupAttachment(GetRootComponent());
}

bool ACCharacter::IsLocallyControlledByPlayer() const
{
	return GetController() && GetController()->IsLocalPlayerController();
}

void ACCharacter::BeginPlay()
{
	Super::BeginPlay();
	ConfigureOverHeadStatusWidget();
}

void ACCharacter::ConfigureOverHeadStatusWidget()
{
	// 检查头顶UI组件是否存在,如果不存在则直接返回
	if (!OverHeadWidgetComponent)
	{
		return;
	}

	// 如果角色由本地玩家控制
	if (IsLocallyControlledByPlayer())
	{
		// 隐藏头顶UI组件
		OverHeadWidgetComponent->SetHiddenInGame(true);
		return;
	}
	// 将头顶UI组件的用户控件对象转换为UOverHeadStatsGauge类型
	UOverHeadStatsGauge* OverheadStatsGuage = Cast<UOverHeadStatsGauge>(OverHeadWidgetComponent->GetUserWidgetObject());
	if (OverheadStatsGuage)
	{
		// 使用能力系统组件配置头顶统计量表
		OverheadStatsGuage->ConfigureWithASC(GetAbilitySystemComponent());
		// 显示头顶UI组件
		OverHeadWidgetComponent->SetHiddenInGame(false);
	}
}

随后在蓝图中设置,于此就能实现头部血条的制作
在这里插入图片描述
在这里插入图片描述

3、血条的些许优化

#pragma region UI
private:
	// 头顶UI
	UPROPERTY(VisibleDefaultsOnly, Category = "UI")
	TObjectPtr<UWidgetComponent> OverHeadWidgetComponent;
	void ConfigureOverHeadStatusWidget();
	/**
	 * @brief 头顶状态条更新间隔时间(秒)\n
	 * 控制头顶UI显示/隐藏检测的刷新频率,单位为秒。\n
	 * 可在编辑器中调整,默认值为1秒。
	 */
	UPROPERTY(EditDefaultsOnly, Category = "UI")
	float HeadStatGaugeVisibilityCheckUpdateGap = 1.f;
	/**
	 * @brief 头顶状态条可见性检测的距离平方阈值\n
	 * 当玩家与角色之间的距离平方小于该值时,显示头顶UI;\n
	 * 可在编辑器中调整,默认值为10,000,000。
	 */
	UPROPERTY(EditDefaultsOnly, Category = "UI")
	float HeadStatGaugeVisibilityRangeSquared = 10000000.f;
	
	// 用于控制头顶状态条可见性更新的定时器句柄
	FTimerHandle HeadStatGaugeVisibilityUpdateTimerHandle;

	/**
	 * @brief 更新头顶状态条可见性\n
	 * 根据玩家与角色之间的距离判断是否启用头顶UI组件的显示。\n
	 * 该方法通过定时器周期性调用。
	 */
	void UpdateHeadGaugeVisibility();
#pragma endregion
void ACCharacter::ConfigureOverHeadStatusWidget()
{
	// 检查头顶UI组件是否存在,如果不存在则直接返回
	if (!OverHeadWidgetComponent)
	{
		return;
	}

	// 如果角色由本地玩家控制
	if (IsLocallyControlledByPlayer())
	{
		// 隐藏头顶UI组件
		OverHeadWidgetComponent->SetHiddenInGame(true);
		return;
	}
	// 将头顶UI组件的用户控件对象转换为UOverHeadStatsGauge类型
	UOverHeadStatsGauge* OverheadStatsGuage = Cast<UOverHeadStatsGauge>(OverHeadWidgetComponent->GetUserWidgetObject());
	if (OverheadStatsGuage)
	{
		// 使用能力系统组件配置头顶统计量表
		OverheadStatsGuage->ConfigureWithASC(GetAbilitySystemComponent());
		// 显示头顶UI组件
		OverHeadWidgetComponent->SetHiddenInGame(false);
		/*******************************下面启动定时器*********************************/
		// 清除之前的定时器,防止重复调用
		GetWorldTimerManager().ClearTimer(HeadStatGaugeVisibilityUpdateTimerHandle);
		// 设置新的定时器,周期性调用 UpdateHeadGaugeVisibility 方法
		// 用于持续检测角色与玩家之间的距离并更新头顶UI可见性状态
		GetWorldTimerManager().SetTimer(
			HeadStatGaugeVisibilityUpdateTimerHandle,     // 定时器句柄
			this,											 // 绑定对象
			&ACCharacter::UpdateHeadGaugeVisibility,		 // 每一定时间调用的函数
			HeadStatGaugeVisibilityCheckUpdateGap,			 // 更新间隔时间(秒)
			true											 // 是否循环调用true为循环,false为单次
		);
	}
}
// 定时器调用的更新函数的实现
void ACCharacter::UpdateHeadGaugeVisibility()
{
	// 获取本地玩家的Pawn角色,用于计算与当前角色的距离
	APawn* LocalPlayerPawn = UGameplayStatics::GetPlayerPawn(this, 0);
	if (LocalPlayerPawn)
	{
		// 计算当前角色与本地玩家之间的平方距离
		float DistSquared = FVector::DistSquared(GetActorLocation(), LocalPlayerPawn->GetActorLocation());

		// 如果距离超过设定的可见范围,则隐藏头顶状态条组件
		OverHeadWidgetComponent->SetHiddenInGame(DistSquared > HeadStatGaugeVisibilityRangeSquared);
	}
}

超出一定距离后ui界面消失
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值