当前位置: 首页 > news >正文

ASC学习笔记0024:移除一个现有的属性集

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

学习内容:

/** 移除一个现有的属性集 */void RemoveSpawnedAttribute(UAttributeSet* Attribute);

这是一个在Gameplay Ability System (GAS) 中常见的函数声明,用于从Ability System Component中移除已添加的属性集。以下是这个函数的典型实现方式:

基本实现

void UYourComponent::RemoveSpawnedAttribute(UAttributeSet* Attribute)
{if (!Attribute || !GetOwnerActor()){return;}// 从已生成的属性集列表中移除SpawnedAttributes.Remove(Attribute);// 如果这个属性集还在主属性集列表中,也从中移除if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){ASC->RemoveSpawnedAttribute(Attribute);}// 可选:销毁属性集对象if (Attribute->IsValidLowLevel()){Attribute->ConditionalBeginDestroy();}
}

更完整的实现示例

void UYourAbilitySystemComponent::RemoveSpawnedAttribute(UAttributeSet* Attribute)
{if (!Attribute){UE_LOG(LogTemp, Warning, TEXT("Attempted to remove null AttributeSet"));return;}if (!SpawnedAttributes.Contains(Attribute)){UE_LOG(LogTemp, Warning, TEXT("AttributeSet not found in SpawnedAttributes"));return;}// 从内部列表中移除SpawnedAttributes.Remove(Attribute);// 从ASC的属性集列表中移除FGameplayAttributeData* AttributeData = nullptr;for (auto It = AttributeSetMap.CreateIterator(); It; ++It){if (It.Value() == Attribute){It.RemoveCurrent();break;}}// 清理并销毁Attribute->PreDestroy();Attribute->ConditionalBeginDestroy();UE_LOG(LogTemp, Log, TEXT("Successfully removed AttributeSet: %s"), *GetNameSafe(Attribute->GetClass()));
}

使用示例

// 假设你有一个对属性集的引用
UAttributeSet* HealthAttributeSet = FindObject<UAttributeSet>(...);// 移除属性集
RemoveSpawnedAttribute(HealthAttributeSet);
HealthAttributeSet = nullptr; // 避免悬空指针

注意事项

  1. 空指针检查:始终验证输入参数

  2. 所有权管理:确保正确管理属性集的生命周期

  3. 组件验证:确认Ability System Component有效

  4. 列表一致性:保持所有相关列表的同步更新

  5. 内存管理:适当销毁不再使用的对象

在GAS中的典型使用场景

  • 动态添加/移除角色的属性集

  • 处理装备系统的属性加成

  • 实现临时的状态效果

  • 清理不再需要的属性数据

这个函数通常在需要动态管理角色属性时使用,特别是在运行时需要修改属性集配置的情况下。

在实际项目中,RemoveSpawnedAttribute 函数在GAS系统中有着广泛的应用场景。以下是一些具体的实际应用案例:

1. 装备系统 - 动态属性管理

// 装备组件中管理装备带来的属性集
void UEquipmentComponent::UnequipItem(UEquipableItem* Item)
{if (!Item || !Item->GetAttributeSet()){return;}// 移除装备提供的属性集if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){ASC->RemoveSpawnedAttribute(Item->GetAttributeSet());}// 从本地记录中移除EquippedAttributeSets.Remove(Item->GetAttributeSet());// 广播装备移除事件OnItemUnequipped.Broadcast(Item);
}// 装备物品时的对应函数
void UEquipmentComponent::EquipItem(UEquipableItem* Item)
{if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){UAttributeSet* NewAttributeSet = NewObject<UAttributeSet>(this, Item->AttributeSetClass);ASC->AddSpawnedAttribute(NewAttributeSet);EquippedAttributeSets.Add(NewAttributeSet);}
}

2. 状态效果系统 - 临时属性加成

// 状态效果组件管理临时属性
void UStatusEffectComponent::RemoveStatusEffect(FGameplayTag EffectTag)
{if (FStatusEffectData* EffectData = ActiveEffects.Find(EffectTag)){if (EffectData->AttributeSet && EffectData->AttributeSet->IsValidLowLevel()){// 移除状态效果对应的属性集if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){ASC->RemoveSpawnedAttribute(EffectData->AttributeSet);}}ActiveEffects.Remove(EffectTag);OnStatusEffectRemoved.Broadcast(EffectTag);}
}// 添加临时状态效果
void UStatusEffectComponent::ApplyStatusEffect(TSubclassOf<UAttributeSet> EffectAttributeClass, float Duration)
{if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){UAttributeSet* NewEffectAttribute = NewObject<UAttributeSet>(this, EffectAttributeClass);ASC->AddSpawnedAttribute(NewEffectAttribute);FStatusEffectData NewEffect;NewEffect.AttributeSet = NewEffectAttribute;NewEffect.RemainingTime = Duration;ActiveEffects.Add(EffectAttributeClass->GetFName(), NewEffect);}
}

3. 职业/专精系统

// 角色职业管理
void UCharacterClassComponent::SwitchClass(UCharacterClass* NewClass)
{if (CurrentClassAttributeSet){// 移除旧职业的属性集if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){ASC->RemoveSpawnedAttribute(CurrentClassAttributeSet);CurrentClassAttributeSet = nullptr;}}// 添加新职业的属性集if (NewClass && NewClass->ClassAttributeSet){UAttributeSet* NewAttributeSet = NewObject<UAttributeSet>(this, NewClass->ClassAttributeSet);if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){ASC->AddSpawnedAttribute(NewAttributeSet);CurrentClassAttributeSet = NewAttributeSet;}}CurrentClass = NewClass;OnClassChanged.Broadcast(NewClass);
}

4. 技能树/天赋系统

// 天赋系统管理选择的属性加成
void UTalentSystemComponent::ResetTalents()
{if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){// 移除所有通过天赋添加的属性集for (UAttributeSet* TalentAttribute : ActiveTalentAttributes){if (TalentAttribute && TalentAttribute->IsValidLowLevel()){ASC->RemoveSpawnedAttribute(TalentAttribute);}}}ActiveTalentAttributes.Empty();SelectedTalents.Empty();// 重新应用基础职业属性ApplyBaseClassAttributes();
}

5. 多人游戏中的同步处理

// 在网络游戏中安全地处理属性集移除
void UPlayerCharacter::Server_RemoveAttributeSet_Implementation(UAttributeSet* AttributeSet)
{if (GetLocalRole() == ROLE_Authority && AttributeSet){// 服务器端移除if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){ASC->RemoveSpawnedAttribute(AttributeSet);}// 通知客户端Multicast_OnAttributeSetRemoved(AttributeSet);}
}// 客户端响应
void UPlayerCharacter::Multicast_OnAttributeSetRemoved_Implementation(UAttributeSet* AttributeSet)
{// 客户端清理本地引用if (GetLocalRole() != ROLE_Authority && AttributeSet){// 避免客户端重复销毁if (OwnedAttributeSets.Contains(AttributeSet)){OwnedAttributeSets.Remove(AttributeSet);}}
}

6. 完整的生命周期管理

// 在角色销毁时清理所有动态属性集
void AAdvancedCharacter::BeginDestroy()
{// 清理所有动态添加的属性集for (UAttributeSet* DynamicAttributeSet : DynamicAttributeSets){if (DynamicAttributeSet && DynamicAttributeSet->IsValidLowLevel()){if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){ASC->RemoveSpawnedAttribute(DynamicAttributeSet);}}}DynamicAttributeSets.Empty();Super::BeginDestroy();
}// 安全的属性集移除函数
void AAdvancedCharacter::SafeRemoveAttributeSet(UAttributeSet* AttributeSet)
{if (!AttributeSet || !IsValid(AttributeSet)){return;}// 检查是否属于这个角色if (!DynamicAttributeSets.Contains(AttributeSet)){UE_LOG(LogGame, Warning, TEXT("Attempting to remove AttributeSet that doesn't belong to this character"));return;}// 从ASC移除if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()){ASC->RemoveSpawnedAttribute(AttributeSet);}// 从本地记录移除DynamicAttributeSets.Remove(AttributeSet);// 标记为待销毁AttributeSet->MarkAsGarbage();
}

实际项目中的最佳实践

  1. 引用管理:始终保持对动态属性集的引用,避免内存泄漏

  2. 网络同步:在多人游戏中确保服务器和客户端状态一致

  3. 错误处理:添加充分的空指针和有效性检查

  4. 生命周期:在适当的时机(如角色销毁、关卡切换)清理属性集

  5. 性能考虑:避免频繁的添加/移除操作,使用属性修饰器(Modifiers)代替

这些实际应用展示了RemoveSpawnedAttribute在构建复杂游戏系统时的重要性,特别是在需要动态修改角色属性的RPG、MMO等游戏类型中。

http://www.dtcms.com/a/618062.html

相关文章:

  • 洛阳做网站公司在哪建设工程信息管理网
  • win10安装miniforge+mamba替代miniconda
  • 旅游类网站策划建设_广告排版设计图片
  • Linux进程间通信三System V 共享内存完全指南原理系统调用与 C 封装实现
  • 云计算与大数据:数字化转型的双重引擎
  • 怎么弄免费的空间做网站铂爵旅拍婚纱摄影官网
  • 郑州中原区网站建设北京冬奥会网页设计
  • Java接口自动化测试之接口加密
  • 插值——Hermite 插值与分段三次 Hermite 插值
  • 外贸建站服务网站计划
  • tcp_Calculator(自定义协议,序列化,反序列化)
  • 【12】FAST角点检测:从算法原理到OpenCV实时实现详解
  • 设计模式实战精讲:全景目录
  • 【2025】 Java 从入门到实战:基础语法与面向对象三大特性巩固练习讲解(附案例练习与答案)
  • Linux:基础开发工具(四)
  • 【USACO25OPEN】It‘s Mooin‘ Time III B
  • OpenGL:Cube Map
  • 《玩转Docker》[应用篇17]:容器可视化管理平台-Docker安装部署Portainer
  • 开平 做一网站建设工程教育网建设工程类的考试辅导网站
  • 多线程 -- 初阶(4) [单例模式 阻塞队列]
  • 如何用VS2017做网站加盟商网站建设
  • HTML 基础知识二:创建容器和表格(附html实战案例)
  • OpenCV(二十八):双边滤波
  • 【2025CVPR物体姿态估计方向】ONDA-Pose:面向自监督六维物体姿态估计的遮挡感知神经域自适应方法
  • 衡阳网站建设开发价格推广关键词排名查询
  • MATLAB基于IOWA-云模型的长距离引水工程运行安全风险评价研究
  • 基层建设论文查询官方网站零基础怎么做电商
  • 跨链如何实现消息互通,消息指的又是什么
  • 手动处理售后太慢?RPA智能处理小红书工单,效率提升1200%[特殊字符]
  • Hello-Agents task4---构建你的智能体框架