[4.9]issues creating dynamic material instance's

ive just upgraded a project to 4.9 from 4.7 and am now having issues creating dynamic material instances in c++.

I have a base material with visual scalar parameters as well as a scalar paramter for a dissolve effect.
within the editor i created 3 material instances and set there visual parameters. i.e color red,green,blue.

I have 3 different c++ staticmesh based classes. And multiple random amounts of each color are spawned at rutime.

previously within the constructor of each class i would create an instance of the one of the already created color instances and apply the material like so.

red,

static ConstructorHelpers::FObjectFinder<UMaterialInstanceConstant> MaterialOb(TEXT("MaterialInstanceConstant'/Game/materials/I_Obstical2.I_Obstical2'"));

	if (StaticMeshComponent && MaterialOb.Object) 
       {
		DynamicMat = UMaterialInstanceDynamic::Create(MaterialOb.Object, this);
		StaticMeshComponent->SetMaterial(0, DynamicMat);
	}

green,

static ConstructorHelpers::FObjectFinder<UMaterialInstanceConstant> MaterialOb(TEXT("MaterialInstanceConstant'/Game/materials/I_Obstical3.I_Obstical3'"));

	if (StaticMeshComponent && MaterialOb.Object) {
		DynamicMat = UMaterialInstanceDynamic::Create(MaterialOb.Object, this);
		StaticMeshComponent->SetMaterial(0, DynamicMat);
	}

ect…

but reading around it apears we can no longer use UMaterialInstanceDynamic::Create within the constructor.
and are supposed to use (UMaterialInstanceDynamic*)MaterialOb.Object.

i.e,

static ConstructorHelpers::FObjectFinder<UMaterialInstanceConstant> MaterialOb(TEXT("MaterialInstanceConstant'/Game/materials/I_Obstical3.I_Obstical3'"));

	if (GetStaticMeshComponent() && MaterialOb.Object) {
		DynamicMat = (UMaterialInstanceDynamic*)MaterialOb.Object;
		GetStaticMeshComponent()->SetMaterial(0, DynamicMat);
	}

The problem with this is in means that all the static mesh actors of a particlular color are now sharing the same material instance.
And adjusting the disovle scalar on one effects them all. ie all the red actors would disovle or all the green actors would disolve.

how are we now supposed to create unique material instances in c++?

Many thanks,

Opamp

Hi Opamp,

I had a similar problem, and as I only started using UE4 recently (4.8), I never had to migrate from an older API. I solved a similar issue in 4.8 as follows. I don’t claim this is the “right” way or anything! There may be a better way - e.g, this is not fast, and you shouldn’t do it often due to the array allocation on the heap. But on a low frequency basis I do this:

   if (AActor* owner = Cast<AActor>(this)) {
      TArray<UMeshComponent*> meshes;
      owner->GetComponents(meshes);
      
      for (auto mesh : meshes) {
         for (int matidx = 0; matidx < mesh->GetNumMaterials(); ++matidx) {
            auto* mat = Cast<UMaterialInstanceDynamic>(mesh->GetMaterial(matidx));

            // Create an instance of this material if there isn't one
            if (mat == nullptr)
               mat = mesh->CreateDynamicMaterialInstance(matidx);
         
            if (mat != nullptr)
               mat->SetVectorParameterValue(whatever);
         }
      }
   }

Perhaps you might be able to raid that bit of code for something you can use.

Yours in analog circuits :slight_smile:

pvz

Thanks for the reply, I’ll have at look at that when I have a chance.
It would be nice to here from Epic about the new way of doing though.

Well ive managed to figure this out.

in the header I need to now add a Umaterial pointer variable.

myactor.h

 UMaterial* BaseMat;

in the constructor

static ConstructorHelpers::FObjectFinder<UMaterial> MatObj(TEXT("Material'/Game/Textures/Master.Master'"));
	if (MatObj.Succeeded()) BaseMat = MatObj.Object;

and the apply the material in postinitializeComponents,

void Amyactor::PostInitializeComponents()
{
	Super::PostInitializeComponents();

	if (BaseMat)
	{
		MaterialInst = UMaterialInstanceDynamic::Create(BaseMat, this);
		PanelComp->SetMaterial(0, MaterialInst);
		MaterialInst->SetScalarParameterValue("Multi", 1);
	}
}

Not in Construst did help. But while in UE4 ,there is no color of material at all… Could any help on it?

You could mark this as answered. It is the best solution I’ve found so far. Thank you