ASC学习笔记0025:移除所有属性集
中文注释:UrealEngine-5.2.1源码-AbilitySystemComponent.h
学习内容:
/** 移除所有属性集 */void RemoveAllSpawnedAttributes();
这是一个在游戏开发(尤其是Unreal Engine)中常见的函数声明。让我来解释它的作用、典型实现方式和使用场景。
函数作用
RemoveAllSpawnedAttributes() 函数用于移除所有通过"生成"(Spawn)方式添加的属性(Attributes),通常用于:
-
清理资源:在对象销毁或重置时释放属性占用的内存
-
状态重置:将对象恢复到初始状态
-
防止内存泄漏:确保动态创建的属性被正确清理
典型实现示例
Unreal Engine C++ 实现
// 在属性管理类中
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++ 实现
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. 角色死亡或重置时
void AMyCharacter::OnDeath()
{// 移除所有战斗中生成的临时属性RemoveAllSpawnedAttributes();// 其他清理逻辑...
}
2. 场景切换时
void AMyGameMode::OnMapChange()
{// 清理所有玩家的生成属性for (APlayerController* Player : Players){if (AMyCharacter* Character = Cast<AMyCharacter>(Player->GetPawn())){Character->RemoveAllSpawnedAttributes();}}
}
3. 技能系统清理
void UMyAbility::EndAbility()
{// 移除该技能生成的所有属性效果RemoveAllSpawnedAttributes();Super::EndAbility();
}
最佳实践
-
在析构函数中调用:
UMyComponent::~UMyComponent()
{RemoveAllSpawnedAttributes();
}
-
添加安全检查:
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)
临时属性效果管理
// 在技能激活时添加属性,结束时清理
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. 装备/道具系统
装备属性管理
// 装备组件
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 系统
状态效果管理
// 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. 多人游戏同步
网络同步清理
// 在网络角色中
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. 场景/关卡管理
关卡切换资源清理
// 游戏模式中
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. 性能优化实践
对象池模式
// 避免频繁的内存分配释放
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. 调试和开发工具
开发者命令
// 控制台命令用于调试
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() 在游戏开发中的关键作用,特别是在管理动态游戏状态、防止内存泄漏和确保系统稳定性方面。
