ASC学习笔记0017:返回此能力系统组件的所有属性列表

中文注释:UrealEngine-5.2.1源码-AbilitySystemComponent.h

学习内容:

cpp 复制代码
/** 返回此能力系统组件的所有属性列表 */
	UFUNCTION(BlueprintPure, Category="Gameplay Attributes")
	void GetAllAttributes(TArray<FGameplayAttribute>& OutAttributes);

这个函数声明看起来是用于获取游戏能力系统中所有属性的方法。以下是关于这个函数的一些补充信息和使用示例:

函数说明

cpp 复制代码
// 在头文件中的完整声明示例
UCLASS()
class YOURGAME_API UYourAbilitySystemComponent : public UAbilitySystemComponent
{
    GENERATED_BODY()

public:
    /** 返回此能力系统组件的所有属性列表 */
    UFUNCTION(BlueprintPure, Category="Gameplay Attributes")
    void GetAllAttributes(TArray<FGameplayAttribute>& OutAttributes);
};

实现示例

cpp 复制代码
void UYourAbilitySystemComponent::GetAllAttributes(TArray<FGameplayAttribute>& OutAttributes)
{
    OutAttributes.Reset();
    
    // 获取所有已注册的属性
    for (const FGameplayAttributeData* AttributeData : GetAttributeDataArray())
    {
        if (AttributeData && AttributeData->GetAttribute())
        {
            OutAttributes.Add(*AttributeData->GetAttribute());
        }
    }
}

Blueprint 使用示例

在蓝图中,你可以这样使用:

  1. 获取所有属性

    • 调用 Get All Attributes 节点

    • 输出到 Out Attributes 数组

  2. 遍历属性

cpp 复制代码
// 伪代码示例
TArray<FGameplayAttribute> AllAttributes;
AbilitySystemComponent->GetAllAttributes(AllAttributes);

for (const FGameplayAttribute& Attribute : AllAttributes)
{
    // 获取属性值
    float Value = AbilitySystemComponent->GetNumericAttribute(Attribute);
    
    // 打印属性名称和值
    FString AttributeName = Attribute.GetName();
    UE_LOG(LogTemp, Warning, TEXT("Attribute %s: %f"), *AttributeName, Value);
}

典型用途

  • UI 显示:在角色状态UI中显示所有属性

  • 调试目的:查看当前所有属性的状态

  • 属性比较:比较不同实体的属性配置

  • 序列化:保存和加载属性状态

注意事项

  • 这个函数返回的是属性定义(FGameplayAttribute),不是具体的数值

  • 要获取属性值,需要另外调用 GetNumericAttribute() 等方法

  • 确保在调用此函数时能力系统组件已正确初始化

在实际项目中,GetAllAttributes 函数有多种重要的应用场景。以下是一些具体的实际用例:

1. UI 属性显示系统

动态属性面板

cpp 复制代码
// 在角色HUD或状态界面中
void UAttributeWidget::UpdateAttributeDisplay()
{
    TArray<FGameplayAttribute> Attributes;
    AbilitySystemComponent->GetAllAttributes(Attributes);
    
    for (const FGameplayAttribute& Attribute : Attributes)
    {
        FAttributeDisplayInfo DisplayInfo;
        DisplayInfo.AttributeName = GetDisplayNameForAttribute(Attribute);
        DisplayInfo.CurrentValue = AbilitySystemComponent->GetNumericAttribute(Attribute);
        DisplayInfo.BaseValue = AbilitySystemComponent->GetNumericAttributeBase(Attribute);
        
        AddAttributeToPanel(DisplayInfo);
    }
}

设置界面 - 属性分配

cpp 复制代码
// 角色升级或创建时的属性分配界面
void UAttributeAllocationWidget::PopulateAttributePoints()
{
    TArray<FGameplayAttribute> CoreAttributes;
    AbilitySystemComponent->GetAllAttributes(CoreAttributes);
    
    // 过滤出可分配的属性(如力量、敏捷、智力等)
    CoreAttributes = CoreAttributes.FilterByPredicate([](const FGameplayAttribute& Attr){
        return IsAllocatableAttribute(Attr);
    });
    
    CreateAttributeSlots(CoreAttributes);
}
复制代码

2. 存档系统

保存所有属性状态

cpp 复制代码
void UPlayerSaveGame::SaveAttributes(UAbilitySystemComponent* ASC)
{
    TArray<FGameplayAttribute> Attributes;
    ASC->GetAllAttributes(Attributes);
    
    SavedAttributes.Empty();
    for (const FGameplayAttribute& Attribute : Attributes)
    {
        FSavedAttributeData SavedData;
        SavedData.Attribute = Attribute;
        SavedData.Value = ASC->GetNumericAttribute(Attribute);
        SavedData.BaseValue = ASC->GetNumericAttributeBase(Attribute);
        
        SavedAttributes.Add(SavedData);
    }
}
复制代码

加载属性状态

cpp 复制代码
void UPlayerSaveGame::LoadAttributes(UAbilitySystemComponent* ASC)
{
    for (const FSavedAttributeData& SavedData : SavedAttributes)
    {
        ASC->SetNumericAttributeBase(SavedData.Attribute, SavedData.BaseValue);
    }
}
复制代码

3. 调试和开发工具

开发者控制台命令

cpp 复制代码
// 控制台命令:显示所有属性
void YourGameModule::ExecuteDumpAttributes(const TArray<FString>& Args)
{
    APawn* PlayerPawn = GetPlayerPawn();
    if (UAbilitySystemComponent* ASC = PlayerPawn->FindComponentByClass<UAbilitySystemComponent>())
    {
        TArray<FGameplayAttribute> Attributes;
        ASC->GetAllAttributes(Attributes);
        
        UE_LOG(LogConsoleResponse, Display, TEXT("=== Player Attributes ==="));
        for (const FGameplayAttribute& Attribute : Attributes)
        {
            float Value = ASC->GetNumericAttribute(Attribute);
            UE_LOG(LogConsoleResponse, Display, TEXT("%s: %.1f"), *Attribute.GetName(), Value);
        }
    }
}
复制代码

实时调试HUD

cpp 复制代码
void UDebugHUD::DrawAttributeDebug()
{
    if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent())
    {
        TArray<FGameplayAttribute> Attributes;
        ASC->GetAllAttributes(Attributes);
        
        float YPos = 100.f;
        for (const FGameplayAttribute& Attribute : Attributes)
        {
            float Value = ASC->GetNumericAttribute(Attribute);
            FString Text = FString::Printf(TEXT("%s: %.1f"), *Attribute.GetName(), Value);
            DrawText(Text, FVector2D(10, YPos), FColor::White);
            YPos += 20.f;
        }
    }
}
复制代码

4. AI 决策系统

基于属性的行为选择

cpp 复制代码
void UCombatAIController::EvaluateCombatOptions()
{
    TArray<FGameplayAttribute> Attributes;
    AbilitySystemComponent->GetAllAttributes(Attributes);
    
    // 分析当前属性状态决定AI行为
    float HealthPercent = GetAttributePercent(UBaseAttributes::GetHealthAttribute());
    float ManaPercent = GetAttributePercent(UBaseAttributes::GetManaAttribute());
    
    if (HealthPercent < 0.3f)
    {
        // 低血量时优先逃跑或使用防御技能
        ExecuteDefensiveBehavior();
    }
    else if (ManaPercent > 0.8f)
    {
        // 高魔法值时使用强力技能
        ExecuteAggressiveBehavior();
    }
}
复制代码

5. 成就和统计系统

属性达成成就

cpp 复制代码
void UAchievementManager::CheckAttributeAchievements()
{
    TArray<FGameplayAttribute> Attributes;
    PlayerASC->GetAllAttributes(Attributes);
    
    for (const FGameplayAttribute& Attribute : Attributes)
    {
        float Value = PlayerASC->GetNumericAttribute(Attribute);
        
        // 检查是否达到某个属性的成就条件
        if (Value >= GetAchievementThreshold(Attribute))
        {
            UnlockAchievement(FString::Printf(TEXT("Master_Of_%s"), *Attribute.GetName()));
        }
    }
}
复制代码

6. 装备和物品系统

属性需求检查

cpp 复制代码
bool UEquipmentComponent::CanEquipItem(const FItemData& Item)
{
    TArray<FGameplayAttribute> PlayerAttributes;
    AbilitySystemComponent->GetAllAttributes(PlayerAttributes);
    
    for (const FAttributeRequirement& Req : Item.AttributeRequirements)
    {
        FGameplayAttribute* PlayerAttr = PlayerAttributes.FindByPredicate([&](const FGameplayAttribute& Attr){
            return Attr == Req.RequiredAttribute;
        });
        
        if (PlayerAttr && AbilitySystemComponent->GetNumericAttribute(*PlayerAttr) < Req.MinimumValue)
        {
            return false; // 属性不足
        }
    }
    return true;
}
复制代码

实际项目中的优化考虑

缓存机制

cpp 复制代码
// 避免每帧调用 GetAllAttributes
void UAttributeMonitorComponent::CacheAttributes()
{
    if (bAttributesDirty)
    {
        CachedAttributes.Empty();
        AbilitySystemComponent->GetAllAttributes(CachedAttributes);
        bAttributesDirty = false;
    }
}
复制代码

属性变化监听

cpp 复制代码
// 监听属性变化,只在变化时更新
void UAttributeMonitorComponent::OnAttributeChanged(const FOnAttributeChangeData& Data)
{
    // 标记需要更新缓存
    bAttributesDirty = true;
    
    // 立即处理变化的特定属性
    HandleAttributeChange(Data.Attribute, Data.NewValue);
}
复制代码

这些实际应用展示了 GetAllAttributes 在游戏系统各个层面的重要性,从核心玩法到工具开发都有广泛用途。

相关推荐
wrj的博客18 小时前
python环境安装
python·学习·环境配置
优雅的潮叭18 小时前
c++ 学习笔记之 chrono库
c++·笔记·学习
星火开发设计18 小时前
C++ 数组:一维数组的定义、遍历与常见操作
java·开发语言·数据结构·c++·学习·数组·知识
月挽清风19 小时前
代码随想录第七天:
数据结构·c++·算法
星幻元宇VR19 小时前
走进公共安全教育展厅|了解安全防范知识
学习·安全·虚拟现实
知识分享小能手19 小时前
Oracle 19c入门学习教程,从入门到精通, Oracle 表空间与数据文件管理详解(9)
数据库·学习·oracle
不大姐姐AI智能体19 小时前
搭了个小红书笔记自动生产线,一句话生成图文,一键发布,支持手机端、电脑端发布
人工智能·经验分享·笔记·矩阵·aigc
点云SLAM20 小时前
C++内存泄漏检测之Windows 专用工具(CRT Debug、Dr.Memory)和Linux 专业工具(ASan 、heaptrack)
linux·c++·windows·asan·dr.memory·c++内存泄漏检测·c++内存管理
浅念-20 小时前
C语言小知识——指针(3)
c语言·开发语言·c++·经验分享·笔记·学习·算法
burning_maple21 小时前
mysql数据库笔记
数据库·笔记·mysql