x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Setting Material and Material Instance In c++ Without Crashing

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.

this is what I'm trying to achieve

alt text

.cpp

alt text

.h

alt text

and this is the error i get from it

alt text

Product Version: UE 4.12
Tags:
temp.jpg (35.2 kB)
temp.jpg (15.3 kB)
temp.jpg (268.0 kB)
temp.jpg (45.9 kB)
more ▼

asked Feb 08 '17 at 04:18 PM in C++ Programming

avatar image

Djekko
19 8 10 11

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Hey Djekko,

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.

Have a great day!

more ▼

answered Feb 08 '17 at 07:14 PM

avatar image

Sean L ♦♦ STAFF
43.5k 485 152 442

avatar image Djekko Feb 08 '17 at 08:05 PM

Thanks for a quick reply

This makes complete sense and I've now implemented it in but I still have the engine crashing.

this is my code now.

This makes complete sense and I've now implemented it in but I still have the engine crashing.

this is my code now.

 static ConstructorHelpers::FObjectFinder<UMaterial> FoundMaterial(TEXT("/Game/ChronosTests/BlackHole/VFX/Materials/M_VolumeSphereMaster2"));
             if (FoundMaterial.Succeeded())
             {
                 ShaderMaterial = FoundMaterial.Object;
             }
             ShaderMatInst = UMaterialInstanceDynamic::Create(ShaderMaterial, MeshComp);
 
             OtherComp->SetMaterial(0, ShaderMatInst);


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.

Any Suggestions?

avatar image Sean L ♦♦ STAFF Feb 08 '17 at 08:14 PM

If you'll notice, in your crash error message:

"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.

avatar image Djekko Feb 08 '17 at 08:26 PM

It works

It's obvious when you explained it back, It's been a long day.

Thanks for the quick replies :)

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question