I’m in the process of converting some of my blueprints to code and I keep hitting this problem. Maybe I’m missing something obvious but it causes the engine to crash when the code should be changing the material.
I see a couple things that I would change in my code:
First, after doing FObjectFinder, you need to check if the search for the object succeeded. For example, if I was looking for ShaderMat, I’d do
if(ShaderMat.Succeeded())
{
}
Here is the full code that I used to set up a dynamic material instance on a static mesh in an actor class.
MyActor.h:
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
UCLASS()
class MATTEST_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UStaticMeshComponent* MeshComp;
UMaterial* StoredMaterial;
UMaterialInstanceDynamic* DynamicMaterialInst;
};
MyActor.cpp
#include "MatTest.h"
#include "MyActor.h"
// Sets default values
AMyActor::AMyActor()
{
// 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"));
static ConstructorHelpers::FObjectFinder<UStaticMesh> FoundMesh(TEXT("/Engine/EditorMeshes/EditorSphere.EditorSphere"));
if (FoundMesh.Succeeded())
{
MeshComp->SetStaticMesh(FoundMesh.Object);
}
static ConstructorHelpers::FObjectFinder<UMaterial> FoundMaterial(TEXT("/Engine/VREditor/BasicMeshes/M_Floor_01.M_Floor_01"));
if (FoundMaterial.Succeeded())
{
StoredMaterial = FoundMaterial.Object;
}
DynamicMaterialInst = UMaterialInstanceDynamic::Create(StoredMaterial, MeshComp);
MeshComp->SetMaterial(0, DynamicMaterialInst);
}
// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AMyActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
Doing this seemed to work perfectly on my end.
Let me know if that helps or if you need any clarification/explanation.
the header files also match yours with the change in names of corse.
Im getting this when th eengine crashes now and dont know what to make fo it.
Fatal error: [File:D:\Build++UE4+Release-4.12+Compile\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp] [Line: 3088]
FObjectFinders can’t be used outside of constructors to find /Game/ChronosTests/BlackHole/VFX/Materials/M_VolumeSphereMaster2
The only other thing that i can make out that could be causing an issue is that im trying to set a material on a primative component not a static mesh component as the component is determained by an overlap event. Ive had a quick look at seeing if i can change a primitive component to a static mesh component but have no luck.
“FObjectFinders can’t be used outside of constructors”. Basically what’s happening is you’re trying to use FObjectFinder outside of your actor’s constructor, which you can’t do. You’ll need to implement this inside of the constructor as I have. You can still assign it later, post construction, but you’ll need to actually find the object in the constructor itself. This should resolve the crash.