中文注释:UrealEngine-5.2.1源码-AbilitySystemComponent.h
学习内容:
cpp
/** 移除所有属性集 */
void RemoveAllSpawnedAttributes();
这是一个在游戏开发(尤其是Unreal Engine)中常见的函数声明。让我来解释它的作用、典型实现方式和使用场景。
函数作用
RemoveAllSpawnedAttributes() 函数用于移除所有通过"生成"(Spawn)方式添加的属性(Attributes),通常用于:
-
清理资源:在对象销毁或重置时释放属性占用的内存
-
状态重置:将对象恢复到初始状态
-
防止内存泄漏:确保动态创建的属性被正确清理
典型实现示例
Unreal Engine C++ 实现
cpp
// 在属性管理类中
void UAttributeSet::RemoveAllSpawnedAttributes()
{
// 遍历并移除所有生成的属性
for (auto& Attribute : SpawnedAttributes)
{
if (Attribute && Attribute->IsValidLowLevel())
{
Attribute->ConditionalBeginDestroy();
}
}
SpawnedAttributes.Empty();
}
// 在Actor或Component中
void UMyAbilitySystemComponent::RemoveAllSpawnedAttributes()
{
if (SpawnedAttributes.Num() > 0)
{
for (UAttributeSet* AttributeSet : SpawnedAttributes)
{
AttributeSet->RemoveAllSpawnedAttributes();
}
SpawnedAttributes.Empty();
}
}
通用 C++ 实现
cpp
class GameCharacter {
private:
std::vector<std::unique_ptr<Attribute>> spawnedAttributes;
public:
void RemoveAllSpawnedAttributes() {
// 清空vector,unique_ptr会自动删除对象
spawnedAttributes.clear();
}
// 添加属性的方法
void AddSpawnedAttribute(std::unique_ptr<Attribute> attribute) {
spawnedAttributes.push_back(std::move(attribute));
}
};
使用场景
1. 角色死亡或重置时
cpp
void AMyCharacter::OnDeath()
{
// 移除所有战斗中生成的临时属性
RemoveAllSpawnedAttributes();
// 其他清理逻辑...
}
2. 场景切换时
cpp
void AMyGameMode::OnMapChange()
{
// 清理所有玩家的生成属性
for (APlayerController* Player : Players)
{
if (AMyCharacter* Character = Cast<AMyCharacter>(Player->GetPawn()))
{
Character->RemoveAllSpawnedAttributes();
}
}
}
3. 技能系统清理
cpp
void UMyAbility::EndAbility()
{
// 移除该技能生成的所有属性效果
RemoveAllSpawnedAttributes();
Super::EndAbility();
}
最佳实践
- 在析构函数中调用:
cpp
UMyComponent::~UMyComponent()
{
RemoveAllSpawnedAttributes();
}
- 添加安全检查:
cpp
void RemoveAllSpawnedAttributes()
{
if (SpawnedAttributes.Num() == 0) return;
// 倒序遍历避免移除时的索引问题
for (int32 i = SpawnedAttributes.Num() - 1; i >= 0; --i)
{
if (SpawnedAttributes[i])
{
SpawnedAttributes[i]->PreRemove();
SpawnedAttributes[i]->ConditionalBeginDestroy();
}
}
SpawnedAttributes.Empty();
}
这个函数是游戏对象生命周期管理中的重要组成部分,确保资源被正确清理,避免内存泄漏和状态混乱。
在实际游戏项目中,RemoveAllSpawnedAttributes() 有着广泛而重要的应用。让我通过几个真实案例来说明:
1. 技能系统(Ability System)
临时属性效果管理
cpp
// 在技能激活时添加属性,结束时清理
void UPoisonDamageAbility::OnAbilityActivate()
{
// 添加中毒效果相关的属性
UAttributeSet* PoisonAttribute = SpawnAttribute(UPoisonAttributeSet::StaticClass());
PoisonAttribute->SetDamagePerSecond(10.0f);
PoisonAttribute->SetDuration(5.0f);
}
void UPoisonDamageAbility::OnAbilityEnd()
{
// 清理中毒效果的所有属性
RemoveAllSpawnedAttributes();
}
// 在技能组件中
void UAbilitySystemComponent::RemoveAllAbilities()
{
// 移除所有技能及其生成的属性
for (auto& Ability : ActiveAbilities)
{
Ability->RemoveAllSpawnedAttributes();
}
ActiveAbilities.Empty();
}
2. 装备/道具系统
装备属性管理
cpp
// 装备组件
void UEquipmentComponent::UnequipAll()
{
// 移除所有装备提供的属性加成
RemoveAllSpawnedAttributes();
// 清空装备列表
EquippedItems.Empty();
}
void UEquipmentComponent::OnItemEquipped(UEquippableItem* Item)
{
if (Item && Item->AttributeSetClass)
{
// 生成装备属性集
UAttributeSet* EquipmentAttributes = SpawnAttribute(Item->AttributeSetClass);
EquipmentAttributes->InitializeFromItem(Item);
}
}
// 切换装备时
void UEquipmentComponent::SwapEquipment(UEquippableItem* NewItem)
{
// 先移除当前装备的所有属性
RemoveAllSpawnedAttributes();
// 再添加新装备属性
if (NewItem)
{
OnItemEquipped(NewItem);
}
}
3. BUFF/DEBUFF 系统
状态效果管理
cpp
// BUFF管理器
void UBuffManager::ApplyBuff(FBuffData BuffData)
{
UAttributeSet* BuffAttributes = SpawnAttribute(UBuffAttributeSet::StaticClass());
BuffAttributes->SetModifiers(BuffData.Modifiers);
BuffAttributes->SetExpireTime(GetWorld()->GetTimeSeconds() + BuffData.Duration);
ActiveBuffs.Add(BuffAttributes);
}
void UBuffManager::ClearExpiredBuffs()
{
float CurrentTime = GetWorld()->GetTimeSeconds();
for (int32 i = ActiveBuffs.Num() - 1; i >= 0; --i)
{
if (ActiveBuffs[i]->GetExpireTime() <= CurrentTime)
{
ActiveBuffs[i]->ConditionalBeginDestroy();
ActiveBuffs.RemoveAt(i);
}
}
}
void UBuffManager::ClearAllBuffs()
{
RemoveAllSpawnedAttributes();
ActiveBuffs.Empty();
}
// 在角色中应用
void AMyCharacter::OnEnterSafeZone()
{
// 进入安全区移除所有负面效果
BuffManager->ClearAllBuffs();
DebuffManager->RemoveAllSpawnedAttributes();
}
4. 多人游戏同步
网络同步清理
cpp
// 在网络角色中
void AMyNetworkCharacter::OnRespawning()
{
if (GetLocalRole() == ROLE_Authority)
{
// 服务器端清理属性
RemoveAllSpawnedAttributes();
// 通知客户端同步清理
Client_RemoveAllSpawnedAttributes();
}
}
// 客户端RPC
void AMyNetworkCharacter::Client_RemoveAllSpawnedAttributes_Implementation()
{
RemoveAllSpawnedAttributes();
}
// 连接断开处理
void AMyGameSession::HandlePlayerDisconnect(APlayerController* Player)
{
if (AMyNetworkCharacter* Character = Cast<AMyNetworkCharacter>(Player->GetPawn()))
{
Character->RemoveAllSpawnedAttributes();
}
}
5. 场景/关卡管理
关卡切换资源清理
cpp
// 游戏模式中
void AMyGameMode::OnPreLoadMap(const FString& MapName)
{
// 清理所有玩家的生成属性
for (APlayerState* PlayerState : GameState->PlayerArray)
{
if (AMyPlayerState* MyPlayerState = Cast<AMyPlayerState>(PlayerState))
{
MyPlayerState->RemoveAllSpawnedAttributes();
}
}
}
// 游戏实例中
void UMyGameInstance::Shutdown()
{
// 游戏关闭时全局清理
UWorld* World = GetWorld();
if (World)
{
for (TActorIterator<AActor> It(World); It; ++It)
{
if (IAttributeInterface* AttributeActor = Cast<IAttributeInterface>(*It))
{
AttributeActor->RemoveAllSpawnedAttributes();
}
}
}
}
6. 性能优化实践
对象池模式
cpp
// 避免频繁的内存分配释放
void UAttributeManager::RemoveAllSpawnedAttributes()
{
for (UAttributeSet* AttributeSet : SpawnedAttributes)
{
// 不立即销毁,而是重置并回收到对象池
AttributeSet->Reset();
AttributePool.Return(AttributeSet);
}
SpawnedAttributes.Empty();
}
UAttributeSet* UAttributeManager::SpawnAttribute(TSubclassOf<UAttributeSet> AttributeClass)
{
UAttributeSet* AttributeSet = nullptr;
// 优先从对象池获取
if (AttributePool.CanProvide(AttributeClass))
{
AttributeSet = AttributePool.Get(AttributeClass);
}
else
{
// 池中无可用对象时创建新实例
AttributeSet = NewObject<UAttributeSet>(this, AttributeClass);
}
SpawnedAttributes.Add(AttributeSet);
return AttributeSet;
}
7. 调试和开发工具
开发者命令
cpp
// 控制台命令用于调试
void AMyCheatManager::RemoveAllAttributes()
{
if (APawn* Pawn = GetPlayerPawn())
{
if (IAttributeInterface* AttributePawn = Cast<IAttributeInterface>(Pawn))
{
AttributePawn->RemoveAllSpawnedAttributes();
UE_LOG(LogTemp, Warning, TEXT("Removed all spawned attributes"));
}
}
}
// 在编辑器中测试
void UMyDeveloperSettings::TestAttributeCleanup()
{
UWorld* World = GEngine->GetWorldContexts()[0].World();
// 测试属性清理功能...
}
这些实际应用展示了 RemoveAllSpawnedAttributes() 在游戏开发中的关键作用,特别是在管理动态游戏状态、防止内存泄漏和确保系统稳定性方面。