I’m experimenting with procedurally adding static meshes to an actor based on variables. Below is a class that fills the height of a box with repeated meshes.
/**
* a simple test class that takes a mesh and repeats it over the z axis
*/
UCLASS()
class MYPROJECT_API AMeshTower : public AActor
{
GENERATED_UCLASS_BODY()
/** the box this volume takes up */
UPROPERTY(VisibleInstanceOnly, Category = Size)
TSubobjectPtr<UBoxComponent> baseBox;
/** the mesh that this actor duplicates */
UPROPERTY(EditAnywhere, Category = Parameters)
UStaticMesh *dupMesh;
/** the construct script, creates the actual geometry */
UFUNCTION()
virtual void OnConstruction(const FTransform& aTransform) override;
};
AMeshTower::AMeshTower(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
baseBox = PCIP.CreateDefaultSubobject<UBoxComponent>(this, TEXT("baseBox"));
baseBox->SetMobility(EComponentMobility::Static);
RootComponent = baseBox;
}
void AMeshTower::OnConstruction(const FTransform& aTransform) {
int spacing = 100;
int32 num_z = baseBox->GetUnscaledBoxExtent().Z/spacing;
for (int32 i = -num_z; i < num_z; i++) {
UStaticMeshComponent *newComp = NewObject<UStaticMeshComponent>(this);
newComp->AttachTo(RootComponent);
newComp->RegisterComponent();
// required for proper GC - this causes the mesh to get automatically destroyed when OnConstruction is re-run
newComp->bCreatedByConstructionScript = true;
UStaticMesh *useMesh = dupMesh;
newComp->SetStaticMesh(useMesh);
FVector loc(0, 0, i * spacing);
newComp->SetRelativeLocation(loc);
newComp->SetMobility(EComponentMobility::Static);
}
}
When clicking build, all static lighting is built correctly. However, when I press play or simulate, the meshes revert to dynamic lighting, and the message “LIGHTING NEEDS TO BE REBUILT (x unbuilt objects(s))”.