So, I’m trying to create a map visualizer using Pocket Worlds plugin from Lyra and trying to get all the actors from the current streaming level, but it keeps only ever returning the actors from Persistent Level, rather than the one streamed in, I can see that the level is properly loaded in the editor)
trying to retrieve the actors for the loaded instances when the level is loaded
TArray<AActor*> OutActors;
for (const auto Instance: LevelInstances)
{
if(const auto Level = Instance->GetStreamingLevel()->GetLoadedLevel())
{
for (AActor* Actor : Level->Actors)
{
OutActors.Add(Actor);
}
}
}
the ‘GetStreamingLevel’ from the Pocket Level instance is a custom code I added, which is just a simple getter
I’m not familiar with the plugin you’re using, but I have done a lot of testing with loading levels and streaming levels. Loading a level doesn’t actually make it visible right away. It take a lot of frames before that happens. If your plugin has an event for OnLevelVisible or OnLevelShown, I’d use that. If not, and you have the level instance, then there should be an event on it called OnLevelShown… like this:
Then you have a UFUNCTION called PostLoadLevel where you put your logic for accessing the actors. Or change the name in quotes.
Once you know for sure the level is loaded, you can then use the LevelInstanceSubsystem to get all actors in a level instance. You’ll have to modify this to put OutActors as a member or something.
bool UMyCustomActor::PostLoadLevel()
{
TArray<AActor*> OutActors;
UWorld* world = this->GetWorld();
ULevelInstanceSubsystem* LevelInstanceSubsystem = UWorld::GetSubsystem<ULevelInstanceSubsystem>(world);
if (LevelInstanceSubsystem)
{
TArray<AActor*> LevelInstanceActors;
UGameplayStatics::GetAllActorsOfClass(world, ALevelInstance::StaticClass(), LevelInstanceActors);
for (int i = 0; i < LevelInstanceActors.Num(); i++)
{
ALevelInstance* LevelActor = Cast<ALevelInstance>(LevelInstanceActors[i]);
if (LevelActor == nullptr)
continue; // Should never happen.
if (!LevelInstanceSubsystem->IsLoaded(LevelActor))
return false; // Something is broken if this happens.
LevelInstanceSubsystem->ForEachActorInLevelInstance(LevelActor, [&OutActors](AActor* Actor)
{
// Ignore World Settings.
if (Actor->IsA<AWorldSettings>())
return true;
if (!Actor->HasActorBegunPlay())
{
// Something is broken.
return false;
}
// Do something with actors.
OutActors.Add(Actor);
return true;
});
}
}
}