GetAllActorsOfClass
是 Unreal Engine 中用于在场景中查找和获取所有指定类型的 Actor 的一种方法。它可以返回所有指定类或其子类的实例,用于在游戏逻辑中批量处理这些 Actor,例如寻找所有敌人、道具、NPC 等。
1. GetAllActorsOfClass
的基本用法
函数定义
static void GetAllActorsOfClass( const UObject* WorldContextObject, TSubclassOf<AActor> ActorClass, TArray<AActor*>& OutActors );
参数说明:
WorldContextObject
:通常是当前的UObject
或World
,用于指定上下文环境,可以使用GetWorld()
。ActorClass
:要查找的 Actor 类的类型,通常是AActor
或AActor
的子类。OutActors
:一个TArray
类型的输出参数,用于存储找到的所有 Actor 实例。
返回值:
- 没有返回值,但所有找到的 Actor 实例会存储在
OutActors
数组中。
使用示例:
#include "Kismet/GameplayStatics.h" // 获取所有 AMyActor 类及其子类的实例 TArray<AActor*> FoundActors; UGameplayStatics::GetAllActorsOfClass(GetWorld(), AMyActor::StaticClass(), FoundActors); for (AActor* Actor : FoundActors) { UE_LOG(LogTemp, Warning, TEXT("Found Actor: %s"), *Actor->GetName()); }
在这个示例中,GetAllActorsOfClass
函数会在当前世界中查找所有 AMyActor
类及其子类的实例,并将它们存储到 FoundActors
数组中。然后我们遍历这个数组,输出每个找到的 Actor 的名称。
2. 常见用法场景
2.1 查找并处理所有敌人
在游戏中,可能需要获取所有敌人并对它们执行某些操作,比如在玩家触发某个事件时,让所有敌人进入警戒状态。
// 获取所有 AEnemyCharacter 类的实例 TArray<AActor*> EnemyActors; UGameplayStatics::GetAllActorsOfClass(GetWorld(), AEnemyCharacter::StaticClass(), EnemyActors); for (AActor* Actor : EnemyActors) { AEnemyCharacter* Enemy = Cast<AEnemyCharacter>(Actor); if (Enemy) { Enemy->EnterAlertState(); // 让敌人进入警戒状态 } }
2.2 查找所有物品道具
在游戏场景中可能需要获取所有道具来显示其位置,或者在游戏开始时检查所有道具的状态。
// 获取所有 ACollectibleItem 类的实例 TArray<AActor*> CollectibleItems; UGameplayStatics::GetAllActorsOfClass(GetWorld(), ACollectibleItem::StaticClass(), CollectibleItems); for (AActor* Item : CollectibleItems) { ACollectibleItem* Collectible = Cast<ACollectibleItem>(Item); if (Collectible) { Collectible->ShowItemLocationOnMap(); // 显示道具位置 } }
2.3 查找特定类型的触发器
在复杂的关卡中,可能有多个触发器,当玩家进入某个区域时,需要禁用或启用所有触发器。
// 获取所有 ATriggerVolume 类的实例 TArray<AActor*> Triggers; UGameplayStatics::GetAllActorsOfClass(GetWorld(), ATriggerVolume::StaticClass(), Triggers); for (AActor* Trigger : Triggers) { ATriggerVolume* TriggerVolume = Cast<ATriggerVolume>(Trigger); if (TriggerVolume) { TriggerVolume->SetActorEnableCollision(false); // 禁用所有触发器的碰撞 } }
2.4 动态修改关卡中的所有光源
在特定事件(例如夜晚到来)时,获取所有光源并改变它们的亮度或颜色。
// 获取所有 ALight 类的实例 TArray<AActor*> Lights; UGameplayStatics::GetAllActorsOfClass(GetWorld(), ALight::StaticClass(), Lights); for (AActor* LightActor : Lights) { ALight* Light = Cast<ALight>(LightActor); if (Light) { Light->SetLightColor(FLinearColor::Blue); // 设置所有光源的颜色为蓝色 Light->SetIntensity(500.0f); // 调整光源的强度 } }
2.5 获取所有玩家角色
在多人游戏中,可以使用 GetAllActorsOfClass
获取所有玩家角色实例,并对它们进行操作。
TArray<AActor*> PlayerCharacters; UGameplayStatics::GetAllActorsOfClass(GetWorld(), APlayerCharacter::StaticClass(), PlayerCharacters); for (AActor* Player : PlayerCharacters) { APlayerCharacter* PlayerCharacter = Cast<APlayerCharacter>(Player); if (PlayerCharacter) { PlayerCharacter->ApplyBuff(); // 给所有玩家角色应用一个 Buff } }
3. 性能注意事项
- 使用频率:
GetAllActorsOfClass
每次调用都会遍历场景中所有的 Actor,性能开销较大。因此,尽量避免频繁调用,特别是在Tick
函数中调用。可以考虑将结果缓存下来或在需要时调用。 - 过滤条件:
GetAllActorsOfClass
只根据类型查找,如果你需要更复杂的过滤条件,可以在查找到所有对象后手动过滤,但要注意性能开销。 - 对象数量:当场景中对象数量很大时(例如数千个对象),频繁调用
GetAllActorsOfClass
可能会导致性能问题。此时可以考虑使用其他方法,例如通过事件驱动的方式管理对象状态。
4. 优化建议
- 缓存结果:如果你知道在一段时间内场景中的对象不会发生变化,可以将结果缓存下来,而不是每次都调用
GetAllActorsOfClass
。 - 分批处理:如果对象数量很多,可以考虑分批次处理对象,而不是一次性处理所有对象。
- 条件查找:尽量使用更具体的类而不是通用的
AActor
类,以减少查找范围和结果集大小。
5. 蓝图中的使用
在蓝图中,你也可以使用 GetAllActorsOfClass
节点来查找特定类型的对象:
- Get All Actors of Class:返回指定类型的所有 Actor 实例。
- 输入参数:
- Class:要查找的 Actor 类。
- 输出参数:
- Out Actors:存储找到的 Actor 列表。
在蓝图中,你可以将这个节点与 For Each Loop
结合使用,对每个找到的 Actor 进行操作。
6. 总结
GetAllActorsOfClass
是查找场景中所有指定类型 Actor 的强大工具,可以用于处理批量对象操作。- 使用时要注意性能问题,尽量避免频繁调用或在对象数量很大的情况下使用。
- 通过缓存结果、分批处理和条件查找等方式优化性能。