Material Index 0 is Invalid

I tried creating a material instance dynamic property in c++ but i’m having a hard time making this actually work:

Here’s the code from my header file:

UPROPERTY(EditAnywhere)
    FColor PlayerColor;
UMaterialInstanceDynamic* MeshMID;

Here’s the code from the constructor in my cpp file:

Mesh3P = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("CharacterMesh3P"));
Mesh3P->SetOwnerNoSee(true);
Mesh3P->SetupAttachment(GetCapsuleComponent());

//Creates a dynamic material instance so that you can change the color of the projectile
MeshMID = Mesh3P->CreateDynamicMaterialInstance(0);
MeshMID->SetVectorParameterValue(FName("DiffuseColor"), PlayerColor);

This code compiles, but when i try to open the editor, i get the error indicated in the title from the log text file.

I don’t really know how the material index works and i found nearly no support regarding this issue, so my question is, what is the correct index?

(Btw i have another class with the exact same setup that will probably get the exact same error)

Thanks!

Hey goncasmage

Mesh3P does not have any SkeletalMeshes set (maybe in editor?)
Thus there is no Material Array you can access to.
The 0 is the index of the Array which you want to get.

If you have set a Skeletal Mesh make sure it actually has a Material attached to it.

Greetings

I have not set any material in the file… so then how do i set a new material instance dynamic? I googled it and didn’t really understand the resources i found, if you could help me i would be grateful!

No Problem,

Your SkeletalMeshComponent should have one ore multiple Materials on it. Default should be one. (It depends on the Exporting from a 3D Modelling Program)
The first thing you have to do is to actually SET a SkeletalMesh for your Component.

You can do this by:

static ConstructorHelpers::FObjectFinder<USkeletalMesh> SkeletalMeshAsset(TEXT("Path To SkeletalMesh"));
if(SkeletalMeshAsset.Object)
    Mesh3P->SetSkeletalMesh(SkeletalMeshAsset.Object);

Mesh3P->CreateMaterialInstanceDynamic(0, Mesh3P->GetMaterial(0));

//or...

static ConstructorHelpers::FObjectFinder<USkeletalMesh> SkeletalMeshAsset(TEXT("Path To SkeletalMesh"));
static ConstructorHelpers::FObjectFinder<UMaterialInterface> MaterialAsset(TEXT("Path To MaterialAsset"));
if(MaterialAsset.Object && SkeletalMeshAsset.Object)
{
    Mesh3P->SetSkeletalMesh(SkeletalMeshAsset.Object);
    Mesh3P->CreateMaterialInstanceDynamic(0, MaterialAsset.Object);
}

You can get the paths to the assets by right clicking on them in the Content Browser of the Unreal Editor and click on “Copy Reference”

Then you paste it and you have your asset loaded.

!!!ConstructorHelpers is only available in the Constructor of you Actor!!!

Greetings

Ok thanks it works! :D… can you just post that as the answer please?

Did it :slight_smile:

I’m glad that this works for you

Good luck

Greetings

Actually, just tried it for real and it can’t change the material color…
This is how i’m doing it in the constructor:

    static ConstructorHelpers::FObjectFinder<USkeletalMesh> SkeletalMeshAsset(TEXT("SkeletalMesh'/Game/Character2/HeroTPP.HeroTPP'"));
static ConstructorHelpers::FObjectFinder<UMaterialInterface> MaterialAsset(TEXT("Material'/Game/FirstPerson/Meshes/BaseMaterial.BaseMaterial'"));
if (MaterialAsset.Object && SkeletalMeshAsset.Object)
{
	GetMesh()->SetSkeletalMesh(SkeletalMeshAsset.Object);
	MeshMID = GetMesh()->CreateDynamicMaterialInstance(0, MaterialAsset.Object);
}

Then on BeginPlay (tried it inside the constructor but wouldn’t work either):

MeshMID->SetVectorParameterValue("DiffuseColor", FColor::Green);

Still won’t work :frowning: :

GetMesh()->SetSkeletalMesh(SkeletalMeshAsset.Object);
MeshMID = GetMesh()->CreateDynamicMaterialInstance(0, MaterialAsset.Object);
GetMesh()->SetMaterial(0, MeshMID);

Try to:

GetMesh->SetMaterial(0, MeshMID); 

Greetings

But the Material is applied to the SkeletalMesh isn’t it?? (Without Parameter changes)

Just wrote it myself.
In my case it works.
The only Bug i found is that you have to delete the Actor and place it in world again to see the changes made. (Maybe that was your problem)

//.h

class USkeletalMeshComponent* SkeletalMeshCompo;
	
UPROPERTY(EditAnywhere) //Not needed
	class UMaterialInstanceDynamic* MID;

//.cpp (Constructor)

static ConstructorHelpers::FObjectFinder<USkeletalMesh> SkeletalMeshAsset(TEXT("SkeletalMesh'/Game/DielsAlderExperiment/Hologram/StepThree/Am_HoloS3.Am_HoloS3_bottle'"));

static ConstructorHelpers::FObjectFinder<UMaterial>		SkeletalMaterial(TEXT("Material'/Game/postproc.postproc'"));

 // 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;

SkeletalMeshCompo = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Skeletal"));

SkeletalMeshCompo->SetSkeletalMesh(SkeletalMeshAsset.Object);
RootComponent = SkeletalMeshCompo;
if (SkeletalMaterial.Object)
{
	MID = (SkeletalMeshCompo->CreateDynamicMaterialInstance(0, SkeletalMaterial.Object));
	SkeletalMeshCompo->SetMaterial(0, MID);
	if (MID)
	{
		MID->SetScalarParameterValue(FName("Opacity"), 0.1f);
		UE_LOG(LogTemp, Warning, TEXT("MID is not null"));
	}
}

If that doesn’t work for you it would be awesome if you could provide a picture of you Material and the scene with the SkeletalMeshActor in it.

Greetings

Hey look at my next reply :slight_smile:

Yes, the GetMesh() function returns the third-person mesh…

The color should be green, white is the default BaseMaterial color:

Still doesn’t work :frowning: :

static ConstructorHelpers::FObjectFinder<USkeletalMesh> SkeletalMeshAsset(TEXT("SkeletalMesh'/Game/Character2/HeroTPP.HeroTPP'"));
static ConstructorHelpers::FObjectFinder<UMaterial> SkeletalMaterial(TEXT("Material'/Game/FirstPerson/Meshes/BaseMaterial.BaseMaterial'"));
GetMesh()->SetSkeletalMesh(SkeletalMeshAsset.Object);
if (SkeletalMaterial.Object) {
    //Mesh3P_MID = GetMesh()->CreateAndSetMaterialInstanceDynamic(0);
Mesh3P_MID = GetMesh()->CreateDynamicMaterialInstance(0, SkeletalMaterial.Object);
GetMesh()->SetMaterial(0, Mesh3P_MID);
if (Mesh3P_MID) {
	//This is executed, checked with a GLog->Log()
	ChangePlayerColor(PlayerColor);
}
}

Already provided a picture of the actor in the scene ;), thanks for the attention btw :smiley: it’s great to have some support on this every once in a while… also if you actually prefer the entire code i can just create a repository or something.

Hm that’s really weird.

The best would be to provide the Project, because I don’t have a clue where the error lies.

Testing it myself should hopefully solve the problem.

EDIT:
No problem. I’m glad to be of any help. It’s always like Puzzle solving to me :smiley:

Just solved it… there was a problem spawning the actor apparently… thanks for the support, it really helped :wink:

Hey cool :slight_smile:
I’m glad that this worked.
What exactly was the problem?

Greetings

Actually the skeletal mesh is still white so it didn’t work quite yet :/, but the projectile had the same issue and now it works, i simply changed the way i was spawning the projectile and it started working.

Hey i discovered something weird… first i spawned a couple projectiles from the static class (C++) and those projectiles did change color accordingly, but if i selected a blueprint that inherits from that C++ class as the spawning actor, it wouldn’t change color… Any ideas on why this might happen?

Hey :slight_smile:

Where do you initialize your Dynamic Material?
If it is in BeginPlay try to Right Click on the BeginPlay Event in your Blueprint and then click on “Add Call to Parent Function”

If that doesn’t change anything you should make a new question and state it as a Bug Report.
In Bug Reports you often get help from Staff Members themselves :slight_smile:

Greetings