在这一篇文章里,我们实现一下技能描述,我们有两个技能描述的框,一个显示当前技能的描述,另一个显示下一级技能的描述。
对于技能的描述,里面会有很多的样式,正常情况下我们是无法创建这么多对面的UI节点,所以,我们需要使用的是,富文本框,在UE里翻译是多格式文本块。
对于做过前端的小伙伴这个应该熟悉,那么接下来,我们实现一下显示。

添加富文本样式

我们需要使用多格式文本块来显示

88. UE5 RPG 使用富文本实现技能描述_UI


将其添加到滚动框内

88. UE5 RPG 使用富文本实现技能描述_UI_02


并将其设置为变量,方便后续使用逻辑修改显示内容

88. UE5 RPG 使用富文本实现技能描述_富文本_03


接下来,我们要创建富文本的样式,需要使用数据表格来实现DataTable

88. UE5 RPG 使用富文本实现技能描述_字符串_04


结构使用RichTextStyleRow

88. UE5 RPG 使用富文本实现技能描述_UI_05


88. UE5 RPG 使用富文本实现技能描述_字符串_06


创建完成,我们添加一行

88. UE5 RPG 使用富文本实现技能描述_UI_07


可以设置对应的文字样式

88. UE5 RPG 使用富文本实现技能描述_ue5_08


接着,我们修改文字使用的字体,大小颜色等内容

88. UE5 RPG 使用富文本实现技能描述_字符串_09


并在多格式文本块上面应用使用此表格

88. UE5 RPG 使用富文本实现技能描述_字符串_10


接着创建文本,我们需要使用<Name></>这种方式来实现设置样式应用的范围,学过html的小伙伴应该最熟悉了

88. UE5 RPG 使用富文本实现技能描述_ue5_11


然后查看样式

88. UE5 RPG 使用富文本实现技能描述_字符串_12


注意,你修改后,需要编译,才能查看效果

88. UE5 RPG 使用富文本实现技能描述_ue5_13


这是我们添加了两个格式后的效果

88. UE5 RPG 使用富文本实现技能描述_富文本_14

如果你设置了Default项的样式,如果没有设置标签的文字,将默认使用Default样式来设置文本。

我们添加多个需要设置的格式,对应内容使用对应的格式。

88. UE5 RPG 使用富文本实现技能描述_ue5_15


接着测试效果即可。

88. UE5 RPG 使用富文本实现技能描述_UI_16

添加技能描述委托

现在,我们创建了可以显示技能描述的UI,接下来,我们在点击技能按钮以后,或者升级技能或降级技能时,技能描述能够根据状态去修改对应的描述,所以,我们需要在技能类里实现获取当前等级的技能描述,并在UI上展示出来。
我们在RPGGameplayAbility.h里增加三个函数,用于获取技能的描述,分别是,当前等级的技能描述,下一等级的技能描述,锁定技能的描述。

virtual FString GetDescription(int32 Level); //获取当前等级的技能描述
	virtual FString GetNextLevelDescription(int32 Level); //获取技能下一等级的技能描述
	static  FString GetLockedDescription(int32 Level); //获取锁定技能描述

接着在cpp文件里实现函数,这里有个注意点,就是如果你使用字符串,需要在字符串前面增加一个L

FString URPGGameplayAbility::GetDescription(int32 Level)
{
	return FString::Printf(TEXT("%s, <Level>%d</>"), L"默认技能名称 - 火球术火球术火球术火球术", Level);
}

FString URPGGameplayAbility::GetNextLevelDescription(int32 Level)
{
	return FString::Printf(TEXT("下一等级:<Level>%d</> 造成更多的伤害。"), Level);
}

FString URPGGameplayAbility::GetLockedDescription(int32 Level)
{
	return FString::Printf(TEXT("技能将在角色等级达到<Level>%d</>时解锁"), Level);
}

如果你不增加,会提示格式不正确

88. UE5 RPG 使用富文本实现技能描述_字符串_17


接着我们在RPGAbilitySystemComponent.h文件里增加一个函数,用于通过技能标签获取技能描述

bool GetDescriptionByAbilityTag(const FGameplayTag& AbilityTag, FString& OutDescription, FString& OutNextLevelDescription); //通过标签获取技能描述

在实现这里,我们使用了引用的方式,可以实现函数修改外部创建的变量的值。如果传入的技能标签无法获取到对于的技能实例,我们将返回锁定技能的描述,如果获取得到,我们将通过实例获取到技能类,并通过类的函数去获取技能描述。

bool URPGAbilitySystemComponent::GetDescriptionByAbilityTag(const FGameplayTag& AbilityTag, FString& OutDescription, FString& OutNextLevelDescription)
{
	//如果当前技能处于锁定状态,将无法获取到对应的技能描述
	if(FGameplayAbilitySpec* AbilitySpec = GetSpecFromAbilityTag(AbilityTag))
	{
		if(URPGGameplayAbility* RPGAbility = Cast<URPGGameplayAbility>(AbilitySpec->Ability))
		{
			OutDescription = RPGAbility->GetDescription(AbilitySpec->Level);
			OutNextLevelDescription = RPGAbility->GetNextLevelDescription(AbilitySpec->Level + 1);
			return true;
		}
	}

	//如果技能是锁定状态,将显示锁定技能描述
	UAbilityInfo* AbilityInfo = URPGAbilitySystemBlueprintLibrary::GetAbilityInfo(GetAvatarActor());
	OutDescription = URPGGameplayAbility::GetLockedDescription(AbilityInfo->FindAbilityInfoForTag(AbilityTag).LevelRequirement);
	OutNextLevelDescription = FString();
	return  false;
}

接着,我们在技能面板里定义一个新的委托类型,专门用于广播技能描述

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FSpellDescriptionSignature, FString, SpellDescription, FString, SpellNextLevelDescription); //技能描述委托

并在类里添加一个委托变量

UPROPERTY(BlueprintAssignable)
	FSpellDescriptionSignature SpellDescriptionSignature; //选中技能按钮后,技能和下一级描述委托

在我们之前实现的BroadcastSpellGlobeSelected函数里,添加委托的广播,这个函数会在鼠标点击技能按钮函数,以及在技能状态修改和技能点变动时被调用。

void USpellMenuWidgetController::BroadcastSpellGlobeSelected()
{
	bool bEnableSpendPoints = false; //技能是否可以升级
	bool bEnableEquip = false; //技能是否可以装配
	bool bEnableDemotion = false; //技能是否可以降级

	ShouldEnableButtons(SelectedAbility.Status, CurrentSpellPoints > 0, bEnableSpendPoints, bEnableEquip, bEnableDemotion); //获取结果

	SpellGlobeSelectedSignature.Broadcast(bEnableSpendPoints, bEnableEquip, bEnableDemotion, SelectedAbility.Level); //广播状态

	//广播技能描述
	FString Description;
	FString NextLevelDescription;
	GetRPGASC()->GetDescriptionByAbilityTag(SelectedAbility.Ability, Description, NextLevelDescription);
	SpellDescriptionSignature.Broadcast(Description, NextLevelDescription);
}

编译打开蓝图,我们在技能UI蓝图里,绑定对当前描述委托的监听,设置技能的文本。

88. UE5 RPG 使用富文本实现技能描述_富文本_18


为了保证能够自动换行,我们需要设置自动包裹文本,英文为 auto warp text更贴切

88. UE5 RPG 使用富文本实现技能描述_富文本_19


接着,我们运行查看效果

88. UE5 RPG 使用富文本实现技能描述_UI_20


然后点击被锁定的技能查看

88. UE5 RPG 使用富文本实现技能描述_ue5_21