Dynamic Mesh Construction

I was able to communicate to the constructor via a singleton.

Even with that, I had to play some games to get this to work.

This method is very finicky:
static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMesh

If you try to pass an *FString into that, it does not work. It wants that text hardwired right there. I have added an if/else statement with all possible meshes and textures. The singleton then communicates which mesh and material to use. I believe this is caching everything at once. I will have to watch my memory footprint to see if I need a different solution. Even if I use a different solution, the code outside of this method will be ignorant of the implementation change.

For reference, here is example code.


This is the calling class requesting an object with rotation, location, scale, mesh and material:

SpawnBlock(FString MeshName, FString MaterialName, FVector Location, FRotator Rotation, FVector Scale) {

// singleton
GlobalClass* globalClass = GlobalClass::instance();
globalClass->setMeshName(MeshName);
globalClass->setMaterialName(MaterialName);

// Location, Rotation and Scale
const FTransform SpawnTransform = FTransform(Rotation, Location, Scale);

ABlock* MyActor = World->SpawnActorDeferred<ABlock>(ABlock::StaticClass(), SpawnTransform);
MyActor->FinishSpawning(SpawnTransform);

}


The ABlock “constructor”. I have 1 mesh and 2 materials for testing.

ABlock::ABlock(const class FObjectInitializer& PCIP) : Super(PCIP) {

// Singleton “side channel” constructor communication
GlobalClass* globalClass = GlobalClass::instance();
FString MeshName = globalClass->getMeshName();
FString MaterialName = globalClass->getMaterialName();

// All possible meshes
if (MeshName == “BLOCK”) {
static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMesh(TEXT(“StaticMesh’/Game/cube_1_texture.cube_1_texture’”));
MyBlock->SetStaticMesh(StaticMesh.Object);
}

// All possible materials
if (MaterialName == “STONE”) {
static ConstructorHelpers::FObjectFinder<UMaterial> Material(TEXT(“Material’/Game/Material.Material’”));
MyBlock->SetMaterial(0, Material.Object);
}
else if (MaterialName == “BLUE”) {
static ConstructorHelpers::FObjectFinder<UMaterial> Material(TEXT(“Material’/Game/Material2.Material2’”));
MyBlock->SetMaterial(0, Material.Object);
}


Now it is super simple for my environment generation logic. Simply call this:
SpawnBlock(“BLOCK”,“STONE”,FVector(XPos, YPos, ZPos), FRotator(0.0f, 0.0f, 0.0f), FVector(scale, scale, scale))

As I add new meshes and materials, I just add them to the ABlock constructor.

I will need to clean up this code but it is working. I did not see complete examples of this on the web. I hope this helps someone down the road…