ASC学习笔记0020:用于定义角色或Actor的默认属性值

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

学习内容:

cpp 复制代码
UPROPERTY(EditAnywhere, Category="AttributeTest")
	TArray<FAttributeDefaults>	DefaultStartingData;

这是一个在虚幻引擎中非常常见的模式,用于定义角色或Actor的默认属性值。以下是详细解析和相关用法:

这个属性的作用:

  • EditAnywhere: 允许在类默认值和实例详情面板中编辑

  • Category="AttributeTest": 在编辑器中将此属性分组到"AttributeTest"类别下

  • TArray<FAttributeDefaults>: 存储属性默认定义的集合

典型的 FAttributeDefaults 结构:

cpp 复制代码
USTRUCT(BlueprintType)
struct FAttributeDefaults
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    FGameplayAttribute Attribute;  // 游戏属性

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    float DefaultValue;  // 默认值
};
复制代码

常见使用模式:

1. 游戏技能系统 (GAS)

cpp 复制代码
// 从默认数据初始化属性
for (const FAttributeDefaults& AttributeDefault : DefaultStartingData)
{
    AbilitySystemComponent->SetNumericAttributeBase(AttributeDefault.Attribute, AttributeDefault.DefaultValue);
}
复制代码

2. 角色初始化

cpp 复制代码
void AMyCharacter::InitializeAttributes()
{
    if (AbilitySystemComponent)
    {
        for (const FAttributeDefaults& Default : DefaultStartingData)
        {
            AbilitySystemComponent->SetNumericAttributeBase(Default.Attribute, Default.DefaultValue);
        }
    }
}
复制代码

3. 数据驱动的方式

通过在蓝图子类或数据资产中配置这个数组,可以创建不同的预设(如"战士"、"法师"、"盗贼")

增强版本示例:

cpp 复制代码
UPROPERTY(EditAnywhere, Category="AttributeTest")
TArray<FAttributeDefaults> DefaultStartingData;

// 辅助函数
float GetDefaultValueForAttribute(const FGameplayAttribute& Attribute) const
{
    for (const FAttributeDefaults& Default : DefaultStartingData)
    {
        if (Default.Attribute == Attribute)
        {
            return Default.DefaultValue;
        }
    }
    return 0.0f; // 或合理的默认值
}
复制代码

实际应用场景:

  • 角色初始属性:生命值、魔法值、攻击力、防御力等

  • 职业模板:为不同职业设置不同的初始属性

  • 装备系统:初始装备带来的属性加成

  • 难度设置:不同难度下的角色初始属性

这种模式非常灵活,适合用于设置游戏中的初始角色属性、装备加成或任何其他基于属性的系统。

在实际项目中,这种默认属性配置系统有广泛的应用场景。以下是一些具体的实际应用案例:

1. 角色职业系统

配置不同职业的初始属性

cpp 复制代码
// 在角色蓝图或数据资产中配置
DefaultStartingData = {
    {HealthAttribute, 100.0f},     // 战士生命值
    {ManaAttribute, 50.0f},        // 战士魔法值
    {StrengthAttribute, 15.0f},    // 战士力量
    {DefenseAttribute, 12.0f}      // 战士防御
};
复制代码

2. 敌人类型配置

不同敌人类型的属性差异

cpp 复制代码
// 小兵敌人
DefaultStartingData = {
    {HealthAttribute, 30.0f},
    {AttackAttribute, 5.0f},
    {MoveSpeedAttribute, 300.0f}
};

// BOSS敌人
DefaultStartingData = {
    {HealthAttribute, 1000.0f},
    {AttackAttribute, 25.0f},
    {DefenseAttribute, 15.0f},
    {MoveSpeedAttribute, 200.0f}
};
复制代码

3. 实际项目中的完整实现

属性集定义

cpp 复制代码
UCLASS()
class YOURGAME_API UMyAttributeSet : public UAttributeSet
{
    GENERATED_BODY()

public:
    UPROPERTY(BlueprintReadOnly, Category = "Health")
    FGameplayAttributeData Health;
    GAMEPLAYATTRIBUTE_PROPERTY_GETTER(UMyAttributeSet, Health)

    UPROPERTY(BlueprintReadOnly, Category = "Mana")
    FGameplayAttributeData Mana;
    GAMEPLAYATTRIBUTE_PROPERTY_GETTER(UMyAttributeSet, Mana)
    
    UPROPERTY(BlueprintReadOnly, Category = "Stats")
    FGameplayAttributeData Strength;
    GAMEPLAYATTRIBUTE_PROPERTY_GETTER(UMyAttributeSet, Strength)
};
复制代码

角色初始化

cpp 复制代码
void AMyCharacter::BeginPlay()
{
    Super::BeginPlay();
    InitializeAttributes();
}

void AMyCharacter::InitializeAttributes()
{
    if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent())
    {
        // 创建属性集
        UMyAttributeSet* AttributeSet = NewObject<UMyAttributeSet>();
        ASC->AddAttributeSetSubobject(AttributeSet);

        // 应用默认属性值
        for (const FAttributeDefaults& DefaultAttr : DefaultStartingData)
        {
            ASC->SetNumericAttributeBase(DefaultAttr.Attribute, DefaultAttr.DefaultValue);
        }
    }
}
复制代码

4. 数据资产驱动配置

创建属性配置数据资产

cpp 复制代码
UCLASS(BlueprintType)
class YOURGAME_API UCharacterAttributeData : public UDataAsset
{
    GENERATED_BODY()

public:
    UPROPERTY(EditAnywhere, Category = "Attributes")
    TArray<FAttributeDefaults> DefaultStartingData;

    UPROPERTY(EditAnywhere, Category = "Visual")
    UTexture2D* Icon;

    UPROPERTY(EditAnywhere, Category = "Visual")
    FText DisplayName;
};
复制代码

在角色中使用数据资产

cpp 复制代码
UPROPERTY(EditAnywhere, Category = "Character Config")
UCharacterAttributeData* CharacterAttributeData;

// 初始化时使用数据资产
void AMyCharacter::InitializeFromDataAsset()
{
    if (CharacterAttributeData)
    {
        DefaultStartingData = CharacterAttributeData->DefaultStartingData;
        InitializeAttributes();
    }
}
复制代码

5. 实际游戏系统集成

RPG游戏中的职业系统

cpp 复制代码
// 战士配置
{
    {HealthAttribute, 120.0f},
    {ManaAttribute, 30.0f},
    {StrengthAttribute, 18.0f},
    {StaminaAttribute, 15.0f},
    {IntelligenceAttribute, 8.0f}
}

// 法师配置  
{
    {HealthAttribute, 80.0f},
    {ManaAttribute, 100.0f},
    {StrengthAttribute, 8.0f},
    {IntelligenceAttribute, 18.0f},
    {SpellPowerAttribute, 15.0f}
}
复制代码

生存游戏中的角色状态

cpp 复制代码
// 生存角色初始状态
{
    {HealthAttribute, 100.0f},
    {HungerAttribute, 100.0f},
    {ThirstAttribute, 100.0f},
    {StaminaAttribute, 100.0f},
    {CarryWeightAttribute, 50.0f}
}
复制代码

6. 编辑器中的优势

在UE编辑器中,你可以:

  • 可视化配置:直接在详情面板中调整数值

  • 批量设置:通过数据资产一次性配置多个角色

  • 版本控制:数据资产便于版本管理和团队协作

  • 热重载:运行时调整数值立即生效

7. 实际项目经验

最佳实践:

  • 使用数据资产而不是直接在蓝图中配置

  • 为不同的敌人类型、职业创建不同的数据资产

  • 添加验证逻辑确保属性配置的完整性

  • 使用枚举或Gameplay Tags来管理属性类型

注意事项:

  • 确保属性名称的一致性

  • 处理属性依赖关系(如最大生命值影响当前生命值)

  • 考虑网络同步的需求

这种模式在实际项目中极大地提高了配置的灵活性和开发效率,特别适合需要大量角色类型和属性配置的RPG、ARPG、生存等游戏类型。

相关推荐
2401_8920709813 小时前
【Linux C++ 日志系统实战】LogFile 日志文件管理核心:滚动策略、线程安全与方法全解析
linux·c++·日志系统·日志滚动
世人万千丶13 小时前
Flutter 框架跨平台鸿蒙开发 - 恐惧清单应用
学习·flutter·华为·开源·harmonyos·鸿蒙
yuzhuanhei13 小时前
Visual Studio 配置C++opencv
c++·学习·visual studio
一轮弯弯的明月14 小时前
贝尔数求集合划分方案总数
java·笔记·蓝桥杯·学习心得
不爱吃炸鸡柳14 小时前
C++ STL list 超详细解析:从接口使用到模拟实现
开发语言·c++·list
十五年专注C++开发14 小时前
RTTR: 一款MIT 协议开源的 C++ 运行时反射库
开发语言·c++·反射
‎ദ്ദിᵔ.˛.ᵔ₎14 小时前
STL 栈 队列
开发语言·c++
此刻觐神14 小时前
IMX6ULL开发板学习-01(Linux文件目录和目录相关命令)
linux·服务器·学习
憧憬从前14 小时前
算法学习记录DAY2
学习
2401_8920709814 小时前
【Linux C++ 日志系统实战】高性能文件写入 AppendFile 核心方法解析
linux·c++·日志系统·文件写对象