Follow up, looks like I got it working just now:
key changes:
- make simple ulevel with a custom hlod actor in it.
- make sure that my main world partition level’s hlodsetup is marked as spatially loaded.
[Image Removed]
details:
In this setup, I have my main World Partition Level
It has a runtime grid: MainGrid
it has an hlodsetup: HLODLayer that is marked as spatially loaded (when I had this not spatially loaded it did not work properly)
I them made a simple new ulevel (Not World Partition)
I put my static mesh into it, and then converted that to an HLOD object with a quick test function, and deleted the static mesh, so I only have the hlod.
(code as example, there are some bugs in this
)
void UTestWorldAssetPluginBPLibrary::TestMakeHLOD(UObject* WorldContextObject, const TArray<AActor*>& InSourceActors)
{
if (InSourceActors.Num() == 0)
return;
AActor* Actor = InSourceActors[0];
FActorSpawnParameters SpawnParams;
SpawnParams.Name = *(FString(Actor->GetName()) + "HLODActor");
SpawnParams.NameMode = FActorSpawnParameters::ESpawnActorNameMode::Required_Fatal;
AWorldPartitionHLOD* HLODActor = WorldContextObject->GetWorld()->SpawnActor<AWorldPartitionHLOD>(AWorldPartitionHLOD::StaticClass(), SpawnParams);
UStaticMeshComponent* Component = nullptr;
UStaticMeshComponent* sourceMeshComponent = Cast<UStaticMeshComponent> (Actor->GetComponentByClass(UStaticMeshComponent::StaticClass()));
if (sourceMeshComponent)
{
Component = NewObject<UStaticMeshComponent>();
Component->SetStaticMesh(sourceMeshComponent->GetStaticMesh());
Component->SetWorldLocation(Actor->GetActorLocation());
}
FVector Origin;
FVector Extents;
Actor->GetActorBounds(false, Origin, Extents, false);
FBox boundingBox(Origin - Extents, Origin + Extents);
HLODActor->SetHLODComponents({ Component });
HLODActor->SetHLODBounds(boundingBox);
}
And then I’m registering the world asset streaming like so:
void UTestWorldAssetPluginBPLibrary::TestWorldAssetStreaming(UObject* WorldContextObject, TSoftObjectPtr<UWorld> InWorldAsset, TSoftObjectPtr<UWorld> InHLODAsset, FTransform Transform, FString MainGrid, FString HLODGrid, bool &Success, FGuid& OutGuid)
{
if (UWorld* World = WorldContextObject->GetWorld())
{
if (UWorldPartition* WorldPartition = World->GetWorldPartition())
{
UWorld* LoadedWorld = InWorldAsset.LoadSynchronous();
UWorld* LoadedHLOD = InHLODAsset.LoadSynchronous();
if (LoadedWorld && LoadedHLOD)
{
UWorldPartition::FRegisterWorldAssetStreamingParams Params;
//levels hlods and grids
Params.SetWorldAsset(InWorldAsset, *MainGrid);
Params.AddHLODWorldAsset(InHLODAsset, *(MainGrid +":" + HLODGrid));
//guid
Params.Guid = FGuid::NewGuid();
//transform and bounds
Params.SetTransform(Transform);
float ChunkRadius = 20.4;
const FVector HalfExtent = FVector(100.0, 100.0, 100.0) * ChunkRadius;
const FVector Center = Transform.GetLocation();
const FBox CellBounds(Center -HalfExtent, Center + HalfExtent);
Params.SetBounds(CellBounds);
//suffix for dedupe
static int ChunkID = 0;
ChunkID++;
FString Suffix = FText::AsNumber(ChunkID).ToString();
Params.SetCellInstanceSuffix(Suffix);
//use our bounds to determine proper grid and cell for placement
Params.SetBoundsPlacement(true);
OutGuid = WorldPartition->RegisterWorldAssetStreaming(Params);
Success = true;
}
}
}
}
Now,
I see my mesh when close, and when I fly far away I see my HLOD pop up.
I think there is probably some issue where not spatially loading the last hlod setup should work but it doesn’t.