中文注释: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 使用示例
在蓝图中,你可以这样使用:
-
获取所有属性:
-
调用
Get All Attributes节点 -
输出到
Out Attributes数组
-
-
遍历属性:
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 在游戏系统各个层面的重要性,从核心玩法到工具开发都有广泛用途。