Setting Dynamic Material Instance for Skeletal/Static meshes using C++?

I am struggling with C++ Programming, I need a book or a course which will cover everything to teach me, so I can make my dream games such as fortnite, freefire, super people, pubg.

Thank You so much in advance.

2 Likes

this will help

and setup the ide will made u start codeing easyer

1 Like

I am done with these things already and have some experience in C++, but when it comes to converting my blueprints to C++ , I have lots of problems to understand the limited introduction of the functions even in the source code and in the original documentation …
I would like to see an official online bp script translation to C++ tool along with the documentation , its easy for UE Developers to make one but I am confused why they don’t have one, its already decades since the engine released and still we are struggling to convert even small nodes to C++.

i`m here too, :rofl: ha ha, i always need google every bp function how to use in cpp

get open source version maybe help,u can double click bp function to check cpp code,but build is so slow

1 Like

I have the source build v4.20 and 27.
I have just find a website to create Blueprint Nodes, its like a small part of he engine online, https://blueprintue.com and this is possible to create a tool in which you create nodes and on the other side you get C++ translation, I Hope UE Developers will think about it. This is something will help everyone to learn the engine quickly.

2 Likes

As someone who just started to dive into the engines code: everything got exponentially easier when I understood how useful searching for definition is.

E. G.: My time googling for function parameters has been reduced to 2 clicks and copy / paste.

3 Likes

but in most cases the 2 clicks and copy / paste will not work… according to my knowledge.
If I am wrong please correct me. I can give you an example setting dynamic material instance in C++, many peoples take it it wrong and they are passing the float values to set parameters… this is wrong because we have the parameters already set up under the material and we want to override one material to the original material in the same slot.

I am struggling to convert this to working C++ code, already 3 days and not working.

What I am trying is:
.h

class UMaterialInterface* MaterialSource;
class UMaterialInstanceDynamic* ReturnDynamicMaterial;

.cpp

void AMyCharacter::SetMaterialInstance()
{
	UMaterialInstanceDynamic* DynMaterialRefference;
	ReturnDynamicMaterial = UMaterialInstanceDynamic::Create(MaterialSource, this, FName("MyDynMat"));
	static ConstructorHelpers::FObjectFinder<UMaterialInterface>MaterialSource(TEXT("/Game/Assets/MyDynMat"));
	if (MaterialSource.Object != nullptr)
	{
		 DynMaterialRefference = ReturnDynamicMaterial ;
		GetMesh()->SetMaterialByName("TopBody.Slot", LocalVariableMaterialRef);
	}
}

The Game compiles, everything is fine… but the material is not giving any result… not effecting anything.

1 Like

Is LocalVariableMaterialRef contains material to set? You created material, saved it to ReturnDynamicMaterial, then copy pointer to material to DynMaterialRefference (I think you can delete variable DynMaterialRefference because you have already saved pointer in class member variable ReturnDynamicMaterial, and DynMaterialRefference is not used in your code). But you don’t copy material to LocalVariableMaterialRef, so, if you haven’t set this variable earlier (in another function, for example), it will contains nullptr.
Also (I have never set C++ variable using ConstructorHelpers::FObjectFinder, so, if I made a mistake, correct me please), I think another problem is you use variable MaterialSource before you set some value using ConstructorHelpers::FObjectFinder.
To sum up, I’ll try fix your function code comparing to what I said. Try this:

void AMyCharacter::SetMaterialInstance()
{
	static ConstructorHelpers::FObjectFinder<UMaterialInterface> MaterialSource(TEXT("/Game/Assets/MyDynMat"));
	ReturnDynamicMaterial = UMaterialInstanceDynamic::Create(MaterialSource.Object, this, FName("MyDynMat"));
	if (MaterialSource.Object != nullptr)
	{
		GetMesh()->SetMaterialByName("TopBody.Slot", ReturnDynamicMaterial);
	}
}
2 Likes

Thank You for Helping Sir, but still the issue is not fixed.
Now I got this error.

[No instance of overloaded function matches argument list.]

Invalid parameter. It means you’re trying to pass ConstructorHelpers::FObjectFinder<UMaterialInterface> instead of UMaterialInterface *. I think UMaterialInterface * presents in FObjectFinder as a member of struct. Try UMaterialInstanceDynamic::Create(MaterialSource.Object, this, FName("MyDynMat"));. I fixed this mistake in my previous reply.

Now the engine is crashing on click to Play.

	static ConstructorHelpers::FObjectFinder<UMaterialInterface> MaterialSource(TEXT("/Game/Assets/my dyn material"));
	//ReturnDynamicMaterial = UMaterialInstanceDynamic::Create(MaterialSource, this, FName("MyDynMat"));
	UMaterialInstanceDynamic::Create(MaterialSource.Object, this, FName("MyDynMat"));
	if (MaterialSource.Object == nullptr)  return;
	{
		GetMesh()->SetMaterialByName("TopBody.Slot", MaterialSource.Object);
	}

What the error is? In which place of this code?
But, why did you changed folder to "/Game/Assets/my dyn material"? Maybe because of this? It was "/Game/Assets/MyDynMat".
Also, now in UMaterialInstanceDynamic::Create(MaterialSource.Object, this, FName("MyDynMat")); you don’t save your new dynamic material. Delete this line and uncomment and change it to ReturnDynamicMaterial = UMaterialInstanceDynamic::Create(MaterialSource.Object, this, FName("MyDynMat")); and change GetMesh()->SetMaterialByName("TopBody.Slot", MaterialSource.Object); to GetMesh()->SetMaterialByName("TopBody.Slot", ReturnDynamicMaterial);.

1 Like

this is the actual directory of the Material, I changed here just to make it short

In my version of engine, it looks like this under UkismetLibrary.cpp

class UMaterialInstanceDynamic* UKismetMaterialLibrary::CreateDynamicMaterialInstance(UObject* WorldContextObject, class UMaterialInterface* Parent)
{
	UMaterialInstanceDynamic* NewMID = NULL;

	if(Parent != NULL)
	{
		NewMID = UMaterialInstanceDynamic::Create(Parent, WorldContextObject);
		if (WorldContextObject == NULL)
		{
			NewMID->SetFlags(RF_Transient);
		}
	}

	return NewMID;
}

This function uses UKismetMaterialLibrary::CreateDynamicMaterialInstance. So rather than including another class, just use it directly like @mnelenpridumivat did:

Like I said, this was the hardest and most important step for me:

1 Like

Now When It return a break point on compilation on 71% and crashed engine.

static ConstructorHelpers::FObjectFinder<UMaterialInterface> MaterialSource(TEXT("/Game/Assets/Characters/FCharacter/Char_01/DynMaterials/DM_FH_01"));
	ReturnDynamicMaterial = UMaterialInstanceDynamic::Create(MaterialSource.Object, this, FName("DM_FH_01"));
	if (MaterialSource.Object == nullptr)  return;
	{
		GetMesh()->SetMaterialByName("F_Head_01_A", ReturnDynamicMaterial);
	}

Still not working, engine crashed while loading at 73%

Try this:

if (MaterialSource.Succeeded())
{
	int MatIndex = GetMesh()->GetMaterialIndex("F_Head_01_A");
	GetMesh()->SetMaterial(MatIndex, ReturnDynamicMaterial);
}
1 Like

same crash and the same breakpoint.