Change StaticMesh material in C++

I’ve been going through some of the other answers on how to change a material on a static mesh using C++, but I’m still running into problems.

I have two main items in my scene - a StaticMeshActor, and a C++ actor called MyActor.

I’m attempting to create a dynamic mesh in MyActor, cache it, and then use it to change the material on the StaticMeshActor as follows:

MyActor.h

UPROPERTY()
UMaterialInstanceDynamic* DynMat;

MyActor.cpp

AMyActor::AMyActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

    ConstructorHelpers::FObjectFinder<UMaterial> Mat(TEXT("/Game/Materials/FlatMaterial.FlatMaterial"));
    if(Mat.Succeeded() == true) {
        UE_LOG(LogTemp, Warning, TEXT("Found Material Template"));
        MaterialTemplate = Mat.Object;
    }
    else {
        UE_LOG(LogTemp, Warning, TEXT("Material Template Not Found"));
    }
    
    DynMat = UMaterialInstanceDynamic::Create(Mat.Object, NULL);
    if(DynMat != NULL) {
        UE_LOG(LogTemp, Warning, TEXT("dynamic material OK"));
    }
    else {
        UE_LOG(LogTemp, Warning, TEXT("dynamic material NULL"));
    }
}

void AMyActor::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

    time += DeltaTime;
    
    if(time >= 2.0f) {
        time = 0.0f;
        UE_LOG(LogTemp, Warning, TEXT("Do Something"));
        
        
        for (TActorIterator<AStaticMeshActor> ActorItr(GetWorld()); ActorItr; ++ActorItr) {
            AStaticMeshActor *StaticMeshActor = *ActorItr;
            
            if(StaticMeshActor->GetHumanReadableName().Contains(TEXT("TheWall"))) {
                UE_LOG(LogTemp, Warning, TEXT("Found TheWall"));
                UStaticMeshComponent *Mesh = StaticMeshActor->GetStaticMeshComponent();
                
                if(Mesh) {
                    
                    UE_LOG(LogTemp, Warning, TEXT("Changed TheWall material ... I think"));
                    Mesh->SetMaterial(0, DynMat);
                    Mesh->MarkRenderStateDirty();
                }
                
            }
            
        }
        
        if(DynMat != NULL) {
        DynMat->SetVectorParameterValue(FName(TEXT("Color")), FLinearColor(FMath::FRandRange(0.0f, 1.0f),
                                                                    FMath::FRandRange(0.0f, 1.0f),
                                                                    FMath::FRandRange(0.0f, 1.0f)));
                                                                    
                                                                    
                                                                    
        UE_LOG(LogTemp, Warning, TEXT("Changed dynamic material color"));
                                                                    
        }
        
    }

}

What happens here is I have a default brick pattern on TheWall, and I’m trying to set it to a different material at runtime. The program runs without crashing or other errors, except that the material on TheWall never changes.

Thanks,

jonbitzen

Did you ever solve this? I found that I can only get the material to change if I call it in BeginPlay() (v4.15.1). If I try to do it anywhere else, it does not work.