ASC学习笔记0013:添加一个新的属性集(初始化为默认值)
中文注释:UrealEngine-5.2.1源码-AbilitySystemComponent.h
学习内容:
/** 添加一个新的属性集(初始化为默认值) */template <class T >const T* AddSet(){return (T*)GetOrCreateAttributeSubobject(T::StaticClass());}
这段代码是一个模板函数,用于动态添加一个新的属性集。让我为您分析一下:
函数分析
函数签名:
template <class T>
const T* AddSet()
功能:
-
创建一个类型为
T的属性集对象 -
使用该类型的默认值进行初始化
-
返回指向新创建对象的常量指针
实现机制:
return (T*)GetOrCreateAttributeSubobject(T::StaticClass());
这里的关键点:
-
T::StaticClass()- 获取类型T的运行时类信息 -
GetOrCreateAttributeSubobject()- 根据类信息获取或创建属性子对象 -
(T*)强制转换 - 将返回的通用指针转换为具体的T*类型 -
返回
const T*- 返回常量指针,防止外部修改
使用示例
假设有一个属性集类:
class FPlayerAttributes
{
public:static UClass* StaticClass() { /* 返回类信息 */ }int32 Health = 100;int32 Mana = 50;float Speed = 1.0f;
};
使用方式:
// 添加新的属性集
const FPlayerAttributes* Attributes = AddSet<FPlayerAttributes>();// 可以读取但不能修改(因为返回const指针)
int32 CurrentHealth = Attributes->Health; // OK
// Attributes->Health = 200; // 编译错误!
设计意图
这种设计通常用于:
-
组件式架构 - 动态添加各种属性组件
-
数据驱动系统 - 运行时根据需要添加属性集
-
序列化系统 - 保持属性集的类型安全
注意事项
-
类型
T必须满足:-
具有
StaticClass()静态方法 -
与属性系统兼容的类结构
-
-
返回
const指针意味着:-
调用者只能读取属性值
-
如果需要修改,可能需要额外的非const版本函数
-
这是一个典型的游戏开发或大型系统中使用的属性管理系统组件。
这个模板函数在游戏开发和各种系统设计中有着广泛的实际应用。以下是几个具体的应用场景:
1. 游戏中的角色属性系统
// 定义不同的属性集
class FCombatAttributes {
public:static UClass* StaticClass();float AttackPower = 10.0f;float Defense = 5.0f;float CriticalChance = 0.1f;
};class FMovementAttributes {
public:static UClass* StaticClass();float MoveSpeed = 600.0f;float JumpHeight = 420.0f;float Acceleration = 2048.0f;
};class FVitalAttributes {
public:static UClass* StaticClass();float Health = 100.0f;float MaxHealth = 100.0f;float HealthRegen = 1.0f;
};// 为游戏角色动态添加属性集
class ACharacter {
public:void InitializeAttributes() {// 添加战斗属性combatAttrs = AddSet<FCombatAttributes>();// 添加移动属性 movementAttrs = AddSet<FMovementAttributes>();// 添加生命属性vitalAttrs = AddSet<FVitalAttributes>();}private:const FCombatAttributes* combatAttrs;const FMovementAttributes* movementAttrs;const FVitalAttributes* vitalAttrs;
};
2. 装备和Buff系统
// 装备提供的属性加成
class FEquipmentBonus {
public:static UClass* StaticClass();float StrengthBonus = 0.0f;float AgilityBonus = 0.0f;float IntelligenceBonus = 0.0f;
};// 临时效果(Buff/Debuff)
class FTimedEffect {
public:static UClass* StaticClass();float Duration = 10.0f;float DamagePerSecond = 5.0f;float SpeedMultiplier = 1.2f;
};// 应用装备和效果
void ApplyEquipment(AActor* Actor, UEquipment* Equipment) {auto bonus = Actor->AddSet<FEquipmentBonus>();// 设置装备加成数值...
}void ApplyBuff(AActor* Actor, UBuff* Buff) {auto effect = Actor->AddSet<FTimedEffect>();// 设置效果参数...
}
3. AI行为配置
// AI感知配置
class FAIPerceptionConfig {
public:static UClass* StaticClass();float SightRadius = 2000.0f;float LoseSightRadius = 2500.0f;float VisionAngleDegrees = 90.0f;
};// AI战斗配置
class FAICombatConfig {
public:static UClass* StaticClass();float AttackRange = 500.0f;float ChaseRange = 1500.0f;float RetreatHealthThreshold = 0.3f;
};// 为AI实体配置行为
void ConfigureAI(AAIEntity* AI) {auto perception = AI->AddSet<FAIPerceptionConfig>();auto combat = AI->AddSet<FAICombatConfig>();// 根据AI类型调整配置if (AI->IsRangedAttacker()) {combat->AttackRange = 800.0f;}
}
4. 技能系统
// 技能效果属性
class FSkillAttributes {
public:static UClass* StaticClass();float Cooldown = 5.0f;float ManaCost = 25.0f;float BaseDamage = 50.0f;float AreaOfEffect = 300.0f;
};// 为技能实例化属性
class USkill {
public:void Initialize() {attributes = GetOwner()->AddSet<FSkillAttributes>();// 设置技能特定属性...}const FSkillAttributes* GetAttributes() const { return attributes; }private:const FSkillAttributes* attributes;
};
5. 配置和存档系统
// 图形设置
class FGraphicsSettings {
public:static UClass* StaticClass();int32 ResolutionX = 1920;int32 ResolutionY = 1080;bool Fullscreen = true;int32 TextureQuality = 2;
};// 游戏设置
class FGameSettings {
public:static UClass* StaticClass();float MouseSensitivity = 1.0f;bool InvertYAxis = false;float MasterVolume = 0.8f;
};// 加载配置
void LoadSettings(UConfigManager* ConfigManager) {auto graphics = ConfigManager->AddSet<FGraphicsSettings>();auto gameSettings = ConfigManager->AddSet<FGameSettings>();// 从文件加载实际配置...
}
6. 网络同步属性
// 网络同步的属性
class FReplicatedAttributes {
public:static UClass* StaticClass();// 这些属性会被自动同步到客户端int32 Score = 0;int32 Kills = 0;int32 Deaths = 0;float GameTime = 0.0f;
};// 为网络对象添加同步属性
void SetupReplication(ANetworkActor* Actor) {auto replicatedAttrs = Actor->AddSet<FReplicatedAttributes>();// 这些属性会自动处理网络同步
}
设计优势
-
类型安全 - 编译时类型检查
-
内存效率 - 按需分配,避免内存浪费
-
灵活性 - 运行时动态组合不同属性集
-
可维护性 - 相关属性集中管理
-
可扩展性 - 新增属性集不影响现有代码
这种模式在需要高度模块化和可组合属性的系统中特别有用,是游戏开发和大型系统架构中的常见实践。
