Setting material functions via c++

Hi, how do i set material functions (material attributes) via c++ during runtime? I could only set parameters like scalar, vector or texture for a material but didnt see set for material functions.

What i was trying to do is to blend two different materials together via material attributes. Since these two materials are pretty unique (lava, whirl pool…), changing basic scalar, vector or texture wouldnt do it.

Or is there another way to approach this. Any advice is appreciated. Thanks in advance.

Hey Pickerz,

The material editor node we create within Unreal generates HLSL code which communicates with the shader. So unfortunately, the blending of two different materials cannot be edited with C++ in Visual Studio.

However, as you have mentioned it is possible to set material variables in C++, it is also possible to create dynamic material instances and bake them into the mesh component of your actor. which they can then be used with Material Functions to create your desired blend effect during run time.

Here is a link to more documentation about: [Instanced Materials][1]

Also here is a code example on setting material instanced in c++

Material Actor.H

 #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "Engine/Classes/Materials/Material.h"
    #include "MaterialActor.generated.h"
    
    UCLASS()
    class TESTINGMATERIALS_API AMaterialActor : public AActor
    {
    	GENERATED_BODY()
    	
    public:	
    	// Sets default values for this actor's properties
    	AMaterialActor();
    
    protected:
    	// Called when the game starts or when spawned
    	virtual void BeginPlay() override;
    
    public:	
    	// Called every frame
    	virtual void Tick(float DeltaTime) override;
    	
    	UPROPERTY(VisibleAnywhere)
    	UStaticMeshComponent* MeshComp;
    
    	UPROPERTY(VisibleAnywhere)
    	UMaterial* StoredMaterial;
    	
    	UPROPERTY(VisibleAnywhere)
    	UMaterialInstanceDynamic* DynamicMaterialInst;

};

Material Actor.Cpp

#include "MaterialActor.h"

// Sets default values
AMaterialActor::AMaterialActor()
{
 	// 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;

	MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
	RootComponent = MeshComp;

	static ConstructorHelpers::FObjectFinder<UStaticMesh>FoundMesh(TEXT("/Engine/EditorMeshes/EditorSphere.EditorSphere"));

	if (FoundMesh.Succeeded())
	{
		MeshComp->SetStaticMesh(FoundMesh.Object);
	}

	static ConstructorHelpers::FObjectFinder<UMaterial>FoundMaterial(TEXT("/Game/StarterContent/Materials/M_CobbleStone_Pebble.M_CobbleStone_Pebble"));

	if (FoundMaterial.Succeeded())
	{
		StoredMaterial = FoundMaterial.Object;
	}

	DynamicMaterialInst = UMaterialInstanceDynamic::Create(StoredMaterial, MeshComp);
	MeshComp->SetMaterial(0, DynamicMaterialInst);
	
}

// Called when the game starts or when spawned
void AMaterialActor::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AMaterialActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

Preview of how it looks in editor:

Hope this helps!

Thanks NicholasMont, i have came up with an alternative method which sort of combine all the materials into a single material. It allows multiple combinations but with very heavy instructions cost. So far it hasnt give me any issues with the frame rate. I will definitely revisit what you have mentioned if it proved too costly in performance for this issue. Thank you for your help.

link text

Hey pickersZ,

I’m glad you’ve found a solution that is working for you. If you ever run into any problems, feel free to open this question back up and report your recent findings.

Thanks!