添加生命值和蓝量的状态标签
添加新的标签
CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Stats_Health_Full)
CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Stats_Health_Empty)
CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Stats_Mana_Full)
CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Stats_Mana_Empty)
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Stats_Health_Full, "Stats.Health.Full", "生命值满")
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Stats_Mana_Full, "Stats.Mana.Full", "法术值满")
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Stats_Health_Empty, "Stats.Health.Empty", "生命值空")
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Stats_Mana_Empty, "Stats.Mana.Empty", "法术值空")
创建无限GE并应用
创建两个GE应用为无限,添加一个组件,死掉和满状态的时候不激活该GE
把两个GE添加到角色中去
监听添加和去除标签
对ASC中监听生命值和法力值的变化进行更改对其添加tag和移除tag(不知道有啥用)
void UCAbilitySystemComponent::HealthUpdated(const FOnAttributeChangeData& ChangeData)
{
if (!GetOwner() || !GetOwner()->HasAuthority()) return;
// 获取当前最大生命值
bool bFound = false;
float MaxHealth = GetGameplayAttributeValue(UCAttributeSet::GetMaxHealthAttribute(), bFound);
// 如果生命值达到最大值,添加生命值已满标签
if (bFound && ChangeData.NewValue >= MaxHealth)
{
if (!HasMatchingGameplayTag(TGameplayTags::Stats_Health_Full))
{
// 仅本地会添加标签
AddLooseGameplayTag(TGameplayTags::Stats_Health_Full);
}
}
else
{
// 移除生命值已满标签
RemoveLooseGameplayTag(TGameplayTags::Stats_Health_Full);
}
if (ChangeData.NewValue <= 0.0f)
{
if (!HasMatchingGameplayTag(TGameplayTags::Stats_Health_Empty))
{
// 本地添加生命值清零标签
AddLooseGameplayTag(TGameplayTags::Stats_Health_Empty);
// 角色死亡
if (DeathEffect)
{
AuthApplyGameplayEffect(DeathEffect);
}
}
}else
{
RemoveLooseGameplayTag(TGameplayTags::Stats_Health_Empty);
}
}
void UCAbilitySystemComponent::ManaUpdated(const FOnAttributeChangeData& ChangeData)
{
// 仅在拥有者存在且为服务器时执行
if (!GetOwner() || !GetOwner()->HasAuthority()) return;
// 获取当前最大魔法值
bool bFound = false;
float MaxMana = GetGameplayAttributeValue(UCAttributeSet::GetMaxManaAttribute(), bFound);
// 如果魔法值达到最大值,添加魔法值已满标签
if (bFound && ChangeData.NewValue >= MaxMana)
{
if (!HasMatchingGameplayTag(TGameplayTags::Stats_Mana_Full))
{
// 仅本地生效的标签
AddLooseGameplayTag(TGameplayTags::Stats_Mana_Full);
}
}
else
{
// 移除魔法值已满标签
RemoveLooseGameplayTag(TGameplayTags::Stats_Mana_Full);
}
// 处理魔法值为零的情况
if (ChangeData.NewValue <= 0)
{
if (!HasMatchingGameplayTag(TGameplayTags::Stats_Mana_Empty))
{
// 添加魔法值清零标签
AddLooseGameplayTag(TGameplayTags::Stats_Mana_Empty);
}
}
else
{
// 移除魔法值清零标签
RemoveLooseGameplayTag(TGameplayTags::Stats_Mana_Empty);
}
}
每秒回复配上UI
public:
// 设置每秒回复值
void SetRegenValueTextToGameplayAttribute(UAbilitySystemComponent* AbilitySystemComponent,const FGameplayAttribute& Attribute);
void SetRegenValue(float NewRegenValue);
private:
void RegenValueChanged(const FOnAttributeChangeData& ChangeData);
// 每秒回复的数值显示,默认为false,小兵不配这个
UPROPERTY(EditAnywhere, Category = "Visual")
bool bRegenValueTextVisible = false;
// 放置右边显示每秒回复的数值
UPROPERTY(VisibleAnywhere, meta = (BindWidget))
TObjectPtr<UTextBlock> RegenValueText;
void UValueGauge::NativePreConstruct()
{
Super::NativePreConstruct();
// 设置进度条颜色
ProgressBar->SetFillColorAndOpacity(BarColor);
ValueText->SetFont(ValueTextFont);
RegenValueText->SetFont(ValueTextFont);
ValueText->SetVisibility(bValueTextVisible ? ESlateVisibility::Visible : ESlateVisibility::Hidden);
ProgressBar->SetVisibility(bProgressBarVisible ? ESlateVisibility::Visible : ESlateVisibility::Hidden);
RegenValueText->SetVisibility(bRegenValueTextVisible ? ESlateVisibility::Visible : ESlateVisibility::Hidden);
}
void UValueGauge::SetRegenValueTextToGameplayAttribute(UAbilitySystemComponent* AbilitySystemComponent,
const FGameplayAttribute& Attribute)
{
if (AbilitySystemComponent)
{
bool bFound;
float Value = AbilitySystemComponent->GetGameplayAttributeValue(Attribute, bFound);
// 如果成功找到对应的属性值,则更新数值指示器的显示
if (bFound)
{
SetRegenValue(Value);
}
// 注册属性变化回调,当属性值发生变化时更新数值指示器显示
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(Attribute).AddUObject(this, &UValueGauge::RegenValueChanged);
}
}
void UValueGauge::SetRegenValue(float NewRegenValue)
{
// 设置数字格式选项,最大小数位数为0
const FNumberFormattingOptions FormatOps = FNumberFormattingOptions().SetMaximumFractionalDigits(0);
// 更新文本显示
RegenValueText->SetText(
FText::Format(
FTextFormat::FromString("{0}/s"), // 格式字符串
FText::AsNumber(NewRegenValue, &FormatOps) // 当前值
)
);
}
void UValueGauge::RegenValueChanged(const FOnAttributeChangeData& ChangeData)
{
SetRegenValue(ChangeData.NewValue);
}
到GameplayWidget
中添加绑定
void UGameplayWidget::NativeConstruct()
{
Super::NativeConstruct();
OwnerAbilitySystemComponent = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(GetOwningPlayerPawn());
if (OwnerAbilitySystemComponent)
{
// 绑定属性回调
HealthBar->SetAndBoundToGameplayAttribute(OwnerAbilitySystemComponent, UCAttributeSet::GetHealthAttribute(), UCAttributeSet::GetMaxHealthAttribute());
ManaBar->SetAndBoundToGameplayAttribute(OwnerAbilitySystemComponent, UCAttributeSet::GetManaAttribute(), UCAttributeSet::GetMaxManaAttribute());
// 绑定每秒回复的属性
HealthBar->SetRegenValueTextToGameplayAttribute(OwnerAbilitySystemComponent, UCHeroAttributeSet::GetHealthRegenAttribute());
ManaBar->SetRegenValueTextToGameplayAttribute(OwnerAbilitySystemComponent, UCHeroAttributeSet::GetManaRegenAttribute());
}
}
构建一下把文本添加进去