1.目标:创建一个数据表,存储一些标签信息
Source/CC_Aura/Public/UI/WidgetController/CC_OverlayWidgetController.h:
cpp
/*数据表行结构:用于存储标签信息*/
USTRUCT(BlueprintType)
struct FUIWidgetRow : public FTableRowBase
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FGameplayTag MessageTag = FGameplayTag(); //标签
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FText Message = FText(); //描述
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TSubclassOf<UCC_UserWidget> MessageWidget; //小部件
UPROPERTY(EditAnywhere, BlueprintReadOnly)
UTexture2D* Image = nullptr; //图片
};
2.C++创建数据表指针:
cpp
protected:
/*消息部件数据表*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Widget Data")
TObjectPtr<UDataTable> MessageWidgetDataTable;
3.在BP_OverlayWidgetController里配置数据表:
(1)蓝图创建数据表:

(2)配置数据表:

4.定义一个模板函数,从标签中找到数据行:
cpp
/*通过标签查找数据表行*/
template<typename T>
T* GetDataTableRowByTag(UDataTable* DataTable, const FGameplayTag& Tag);
cpp
template <typename T>
T* UCC_OverlayWidgetController::GetDataTableRowByTag(UDataTable* DataTable, const FGameplayTag& Tag)
{
return DataTable->FindRow<T>(Tag.GetTagName(), TEXT(""));
}
CC_OverlayWidgetController.cpp:

有红线,报错.这是因为Lambda函数是匿名函数,需要在[ ]里添加"this":

cpp
CC_AbilitySystemComponent->OnEffectAssetTags.AddLambda(
[this](const FGameplayTagContainer& AssetTags)
{
for(const FGameplayTag& Tag : AssetTags)
{
//对标签进行检测,如果不是信息标签,将无法进行广播
FGameplayTag RequestGameplayTag = FGameplayTag::RequestGameplayTag(FName("Message"));
if (Tag.MatchesTag(RequestGameplayTag)) //检测Tag是否是RequestGameplayTag的子标签
{
FUIWidgetRow* Row = GetDataTableRowByTag<FUIWidgetRow>(MessageWidgetDataTable, Tag);
}
}
}
);
5.现在我们的目的是:将数据表的行信息,广播给小部件
(1)所以,创建一个动态多播委托:
cpp
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMessageWidgetRowSignature, FUIWidgetRow, Row);
(2)定义委托
cpp
/*委托:消息行*/
UPROPERTY(BlueprintAssignable, Category="GAS|Messages")
FOnMessageWidgetRowSignature OnMessageWidgetRowSignature;
(3)广播值的变化:

6.打开蓝图WBP_Overlay:
绑定委托事件:

7.GameplayEffect里添加标签:

完美