How to create, for example, several thousand trees from a script and make it work reliably.
I’m trying to do it this way
FString PathEuro = TEXT("/Game/Megascans/3D_Plants/EuropeanHornbeam/Geometry/SimpleWind/");
HISMAdd(PathEuro + TEXT("SM_EuropeanHornbeam_Forest_02.SM_EuropeanHornbeam_Forest_02"));
HISMAdd(PathEuro + TEXT("SM_EuropeanHornbeam_Field_02.SM_EuropeanHornbeam_Field_02"));
HISMAdd(PathEuro + TEXT("SM_EuropeanHornbeam_Forest_08.SM_EuropeanHornbeam_Forest_08"));
SpawnTrees();
}
void AGameManager::HISMAdd(const FString& Path){
if(!RootComponent){ return; }
UStaticMesh* Mesh = LoadObject<UStaticMesh>(nullptr, *Path);
if(!Mesh){ return; }
int32 Num = MapHISM.Num();
FString Name = FString::Printf(TEXT("HISM_%d"), Num);
UHierarchicalInstancedStaticMeshComponent* HISM = NewObject<UHierarchicalInstancedStaticMeshComponent>(this, *Name);
if(!HISM){ return; }
HISM->SetupAttachment(RootComponent);
HISM->RegisterComponent();
HISM->SetCullDistances(0.0f, 30000.0f);
HISM->SetMobility(EComponentMobility::Stationary);
HISM->bAffectDynamicIndirectLighting = true;
HISM->bCastDynamicShadow = true;
HISM->SetCastShadow(true);
HISM->SetStaticMesh(Mesh);
MapHISM.Add(Num, HISM);
}
void AGameManager::SpawnTrees(){
if(MapHISM.Num() == 0){ return; }
const float DistanceBetweenObjects = 2000.0f;
const float RandomOffset = 200.0f;
const int32 MinX = 0, MaxX = 50000;
const int32 MinY = 0, MaxY = 50000;
int32 Count = 0, CountMax = 1000;
for(float X = MinX; X <= MaxX; X += DistanceBetweenObjects){
for(float Y = MinY; Y <= MaxY; Y += DistanceBetweenObjects){
if(Count > CountMax){ return; }
Count++;
int32 RandomNum = FMath::RandRange(0, 2);
if(!MapHISM.Contains(RandomNum)){ continue; }
float RandX = FMath::FRandRange(-RandomOffset, RandomOffset);
float RandY = FMath::FRandRange(-RandomOffset, RandomOffset);
FVector Location(X + RandX, Y + RandY, 0.0f);
FRotator Rotation(0.0f, FMath::FRandRange(0.0f, 360.0f), 0.0f);
FVector Scale(FMath::FRandRange(1.0f, 2.0f));
FTransform Transform(Rotation, Location, Scale);
if(!MapHISM[RandomNum]->AddInstance(Transform)){ UE_LOG(DebugLog, Error, TEXT("HISM FALSE")); }
}
}
}
This creates 1,000 trees as intended, but the frame rate drops below 30, and in some places, to 10. But if I create a scene using the “grass” tool with the same 1,000 trees (and even several times more), everything runs consistently above 60 fps. So, is it possible to do the same thing from code? (That is, dynamically create 1,000 trees when the scene starts)