I have been unable to get a material on an InstancedStaticMeshComponent, and unable to find any code examples on the forums or AnswerHub showing how it might be done. I have tested my code by putting in both a StaticMeshComponent and an InstancedStaticMeshComponent. The material applies to the SMC, but not the ISMC. I’m sure there’s something obvious I’m missing. Please advise.
Block.cpp
AArchBlock::AArchBlock(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
PrimaryActorTick.bCanEverTick = true;
// capsule component for root
CapsuleComponent = PCIP.CreateDefaultSubobject<UCapsuleComponent>(this, "MyCapsuleComponent");
CapsuleComponent->InitCapsuleSize(100.0f, 200.0f);
CapsuleComponent->BodyInstance.bEnableCollision_DEPRECATED = true;
static FName CollisionProfileName(TEXT("Pawn"));
CapsuleComponent->SetCollisionProfileName(CollisionProfileName);
RootComponent = CapsuleComponent;
//-----------------------------------------------------------------------
// staticmeshcomponent, called blockstaticmeshcomponent here
static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshFinder(TEXT("StaticMesh'/Game/Shapes/Shape_Cube.Shape_Cube'"));
AssetSM_BlockStaticMesh = StaticMeshFinder.Object;
BlockStaticMeshComponent = PCIP.CreateDefaultSubobject < UStaticMeshComponent >(this, TEXT("BlockStaticMeshComponent"));
BlockStaticMeshComponent->SetStaticMesh(AssetSM_BlockStaticMesh);
SetupSMComponentsWithCollision(BlockStaticMeshComponent);
BlockStaticMeshComponent->AttachParent = CapsuleComponent;
BlockStaticMeshComponent->SetMobility(EComponentMobility::Movable);
BlockStaticMeshComponent->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryOnly);
BlockStaticMeshComponent->BodyInstance.SetObjectType(ECC_WorldDynamic);
BlockStaticMeshComponent->BodyInstance.SetResponseToAllChannels(ECR_Ignore);
BlockStaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldStatic, ECR_Block);
BlockStaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldDynamic, ECR_Block);
//-----------------------------------------------------------------------
// instancedstaticmeshcomponent
static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshOb(TEXT("StaticMesh'/Game/Shapes/Shape_Cube.Shape_Cube'"));
SMAsset_Cube = StaticMeshOb.Object;
InstancedStaticMeshComponent = PCIP.CreateDefaultSubobject<UInstancedStaticMeshComponent>(this, TEXT("InstancedStaticMeshComponentCOMP"));
InstancedStaticMeshComponent->AttachParent = RootComponent;
InstancedStaticMeshComponent->SetStaticMesh(SMAsset_Cube);
InstancedStaticMeshComponent->bOwnerNoSee = false;
InstancedStaticMeshComponent->bCastDynamicShadow = false;
InstancedStaticMeshComponent->CastShadow = false;
InstancedStaticMeshComponent->BodyInstance.SetObjectType(ECC_WorldDynamic);
InstancedStaticMeshComponent->SetHiddenInGame(false);
InstancedStaticMeshComponent->SetMobility(EComponentMobility::Movable);
InstancedStaticMeshComponent->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryOnly);
InstancedStaticMeshComponent->BodyInstance.SetObjectType(ECC_WorldDynamic);
InstancedStaticMeshComponent->BodyInstance.SetResponseToAllChannels(ECR_Ignore);
InstancedStaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldStatic, ECR_Block);
InstancedStaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldDynamic, ECR_Block);
//-----------------------------------------------------------------------
// find and apply materials
static ConstructorHelpers::FObjectFinder <UMaterial>MaterialFinder(TEXT("Material'/Game/Materials/M_Brick_Clay_Beveled.M_Brick_Clay_Beveled'"));
if (MaterialFinder.Object != NULL)
{
MyMaterial = (UMaterial*)MaterialFinder.Object;
}
MyMaterialDynamic = UMaterialInstanceDynamic::Create(MyMaterial, this);
InstancedStaticMeshComponent->SetMaterial(0, MyMaterialDynamic);
BlockStaticMeshComponent->SetMaterial(0, MyMaterialDynamic);
}
And Block.h
UCLASS()
class ARCH_API AArchBlock : public AActor
{
GENERATED_UCLASS_BODY()
UPROPERTY()
TSubobjectPtr<UInstancedStaticMeshComponent> InstancedStaticMeshComponent;
UPROPERTY()
UStaticMesh* SMAsset_Cube;
TSubobjectPtr<UStaticMeshComponent> BlockStaticMeshComponent;
UStaticMesh * AssetSM_BlockStaticMesh;
TSubobjectPtr<UCapsuleComponent> CapsuleComponent;
UMaterial* MyMaterial;
UMaterialInstanceDynamic* MyMaterialDynamic;
}
And the code from which it the spawning is called
FActorSpawnParameters MySpawnParams;
MySpawnParams.bNoCollisionFail = true;
AArchBlock* NewBlock = GetWorld()->SpawnActor<AArchBlock>(AArchBlock::StaticClass(), FVector(0, 0, 0), FRotator(0, 0, 0), MySpawnParams);
FTransform newT = NewBlock->GetTransform();
newT.SetLocation(FVector(-300, -300, -300));
NewBlock->InstancedStaticMeshComponent->AddInstance(newT);
newT.SetLocation(FVector(300, 300, 300));
NewBlock->InstancedStaticMeshComponent->AddInstance(newT);