Could you please paste your updated code?
static ConstructorHelpers::FObjectFinder<UMaterialInterface> MaterialSource(TEXT("/Game/Assets/Characters/FCharacter/Char_01/DynMaterials/DM_FH_01"));
ReturnDynamicMaterial = UMaterialInstanceDynamic::Create(MaterialSource.Object, this);
//if (MaterialSource.Object == nullptr) return;
//{
// GetMesh()->SetMaterialByName("F_Head_01_A", ReturnDynamicMaterial);
//}
if (MaterialSource.Succeeded())
{
int MatIndex = GetMesh()->GetMaterialIndex("F_Head_01_A");
GetMesh()->SetMaterial(MatIndex, ReturnDynamicMaterial);
}
I googled a bit, try to change ReturnDynamicMaterial = UMaterialInstanceDynamic::Create(MaterialSource.Object, this);
to ReturnDynamicMaterial = UMaterialInstanceDynamic::Create(MaterialSource.Object, GetWorld());
(change second parameter, maybe InOuter
parameter means world context, not actor).
it runs compiled successfully, but the material is not effecting the head
I suggest you leave it as is was, comment every line, and start testing one by one compiling until you get to the crash.
This is working for me:
void ADynamicMatTest::SetDynamicMat()
{
static ConstructorHelpers::FObjectFinder<UMaterialInterface>Material(
TEXT("/Game/Blueprints/Misc/M_ToCreateInstance.M_ToCreateInstance")
);
UMaterialInstanceDynamic* DynamicMaterial = UMaterialInstanceDynamic::Create(
Material.Object,
this,
FName("M_CreatedInstance")
);
if (Material.Succeeded())
{
StaticMesh->SetMaterial(0, DynamicMaterial);
}
}
Your problem could easily be a bad path to the material.
This works fine, but it deletes the base material didnāt override it, But the main thing is we found an internal engine bug, we canāt set material by name using C++, and setting it by blueprint working fine as I shown in the image.
Thank You very mush for helping and Solving this Issue. Sir thank You very very much. I was struggling with this from 3 days.
The above solutions from mnelenpridumivat should also work logically but because of the engine bug they donāt work.
Perfectly working.
ik itās marked as solved, just wanted to share these⦠they also work:
void ADynamicMatTest::GetMaterialFromPath(FString MatPath) // Use in Constructor
{
const TCHAR* Dir = *MatPath;
// Find existing material
static ConstructorHelpers::FObjectFinder<UMaterial>NewMaterial(Dir);
// Store in UMaterial* variable
if (NewMaterial.Succeeded())
{
MyMaterial = NewMaterial.Object;
}
}
void ADynamicMatTest::CreateAndApplyNewDynMatInst(
UMaterial* Mat,
UStaticMeshComponent* Mesh,
FName SlotName,
FName DynInstName
) // Use in or after BeginPlay
{
// Check for nullptr
check(Mat);
check(Mesh);
// Create dynamic material instance
UMaterialInstanceDynamic* DynamicMaterial = UMaterialInstanceDynamic::Create(
Mat,
this,
DynInstName
);
// Search material slot by name
int MatIndex = Mesh->GetMaterialIndex(SlotName); // 0
// Check for valid slot
if(MatIndex != -1)
{
// Apply material at index
Mesh->SetMaterial(MatIndex, DynamicMaterial);
}
else
{
UE_LOG(LogTemp, Error, TEXT("SlotName not found."));
}
}
void ADynamicMatTest::CreateAndApplyNewDynMatInst(
UMaterial* Mat,
UStaticMeshComponent* Mesh,
int MatIndex,
FName DynInstName
) // Use in or after BeginPlay
{
// Check for nullptr
check(Mat);
check(Mesh);
if (MatIndex >= Mesh->GetMaterialSlotNames().Num())
{
UE_LOG(LogTemp, Error, TEXT("MatIndex out of scope."));
return;
}
// Create dynamic material instance
UMaterialInstanceDynamic* DynamicMaterial = UMaterialInstanceDynamic::Create(
Mat,
this,
DynInstName
);
// Apply material at index
Mesh->SetMaterial(MatIndex, DynamicMaterial);
}
Sir , Thank You very much for this, I saved it in my disk in a text document, in the near time I will working on a big workflow with materials and I will post many problems , I hope You will look into them. Thank You very much for these Solutions.
Sir, For some reasons the materials is not working from today again, I didnāt modify the code and everything is the same as before⦠I donāt know what is the reason. The game compiles and logs āthe material found successfullyā but not effecting the head.
Could you share both .h and .cpp?
Sure, I will share them now in a minute
MyCharacter.h (12.5 KB)
MyCharacter.cpp (25.3 KB)
The Function InitSkeletalMesh is responsible to set materials.
Donāt see anything wrong with that specifically and its not giving you any errors⦠my old project is also having same issueā¦
Found a quick solution though. You could implement this and run the function there: AActor::OnConstruction | Unreal Engine Documentation
Tested and it works.
From Actor.h:
/**
* Called when an instance of this class is placed (in editor) or spawned.
* @param Transform The transform the actor was constructed at.
*/
virtual void OnConstruction(const FTransform& Transform) {}
and when I implement the initskeletalmeash
using blueprint, everything works fine⦠the same way calling it under constructor using blueprints.
There is some difference between the constructor of blueprints and C++.
I think this is because the blueprint constructor is running after the editor starts and the c++ constructor is running before the editor starts.
This .
I tried to make the function blueprintcallable to call it under blueprint constructor, but the editor crashed on this approach.
Changing this
to NULL
(Material_H.Object, NULL, FName("Material_Instance"));
works and I have no Idea what is going on but I am sure at some point it will also stop working as before you know the situation ⦠already my head is burning ⦠looking like the situation is forcing me to build the game with blueprintsā¦