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"

Garbage Collection of UMaterialInstance objects stored in TMap

I'm having issues storing a TMap (called cachedMaterials) with keys of type class UMaterialInstance*. I need to ensure they're not GCed, but can't use TMaps (since UPROPERTY() doesn't work for them), and the alternative of using material->AddToRoot() / setting flags to RF_RootSet causes a crash in editor when ending play, presumably because the materials are not removed from the root (commenting out the offending root-setting line prevents the crash).

I've tried using material->RemoveFromRoot() during BeginDestroy(), but I'm still crashing when exiting play mode.

The thought crossed my mind to store those materials in a UPROPERTY() TArray arrayJustToPreventGC;, but that seems hackish...

The cachedMaterials TMap is used to map each StaticMeshActor to copied instances of their TArray of materials in a for loop, using something resembling this:

 TArray dynamicMaterials;
 UPrimitiveComponent* pc = someStaticMeshActor->GetRootPrimitiveComponent();
 for (for (int i=0; iGetNumMaterials(); i++)
 {
     UMaterialInstanceDynamic* tempMaterial = pc->CreateAndSetMaterialInstanceDynamicFromMaterial( i, pc->GetMaterial(i) )
     tempMaterial->AddToRoot(); //or tempMaterial->SetFlags(RF_RootSet);
     dynamicMaterials.Add( tempMaterial );
 }
 cachedMaterials.Add( someStaticMeshActor, dynamicMaterials );

Since TMaps can't be used with UPROPERTY(), I can't use that pattern to prevent the material instances created at runtime from being GCed. I've also tried using class UMaterialInstanceDynamic* as the TMap's value type, but the issues remain. I'm presuming this issue applies to UObjects generally, since they're subject to garbage collection unless referenced / part of the root set?

Any help would be greatly appreciated!

Cheers, Steve

Product Version: Not Selected
Tags:
more ▼

asked Mar 11 '14 at 02:39 AM in C++ Programming

avatar image

ue4-archive ♦♦ STAFF
50k 3670 1999 9124

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

2 answers: sort voted first

Just a note for anyone currently running into this issue before TMaps become compatible with UPROPERTY() - I ended up preventing the crash by also storing materials created at runtime in a TArray, declared as such:

 //Not able to use UPROPERTY() to prevent the UMaterialInterface objects
 //created at runtime from being garbage collected, and using AddToRoot()
 //or SetFlags(RF_RootSet) was causing crashes after ending play in editor.
 TMap> cachedMaterials; //map of static mesh actors, each element with an array of materials

 //An array whose elements are safe from garbage collection since it's a UPROPERTY().
 UPROPERTY()
 TArray HackToStopEditorCrash;

Then, when when creating a new dynamic material instance, I did this:

 //the "a" variable is a pointer to a StaticMeshActor
 TArray dynamicMaterials;
 UPrimitiveComponent* pc = a->GetRootPrimitiveComponent();
 for (int i=0; iGetNumMaterials(); i++)
 {
     //create dynamic instance of the PrimitiveComponent's i-th material
     UMaterialInstanceDynamic* tempMaterial = pc->CreateDynamicMaterialInstance(i);

     //HACK: add dynamic material to a UPROPERTY()-ed TArray to prevent GC and gracefully end PIE
     HackToStopEditorCrash.Add(tempMaterial);

     //add tempMaterial to dynamicMaterials, to be stored in the cachedMaterials TMap
     dynamicMaterials.Add(tempMaterial);
 }
 cachedMaterials.Add(a,dynamicMaterials);

Thanks for the help, guys. This workaround seems like the best solution for now, and should be no problem to remove once TMaps work with UPROPERTY(), since my code makes no other use of the HackToStopEditorCrash array and any lines referencing it can then safely be deleted.

more ▼

answered Mar 11 '14 at 02:39 AM

avatar image

ue4-archive ♦♦ STAFF
50k 3670 1999 9124

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

Why Need TMap?

Why do you need a TMap instead of just using a TArray and setting up all the proper accessors?

I am quite curious,

I am not presuming I know one way better than another, just want more info as to why TMap is your preferred design choice

Rama

more ▼

answered Mar 11 '14 at 02:39 AM

avatar image

ue4-archive ♦♦ STAFF
50k 3670 1999 9124

avatar image ue4-archive ♦♦ STAFF Mar 11 '14 at 02:39 AM

If I had to guess it's because TMap is Key-Value storage, while TArray is just Value (object). And he needs that key for something.

avatar image ue4-archive ♦♦ STAFF Mar 11 '14 at 02:39 AM

Lukasz is correct - I want to map each StaticMeshActor in the game to a TArray of materials copied from its array of materials element by element.

Even if this isn't the best way to go about doing that, I'd still be interested to know how to solve this issue with TMaps. I could use a TMap with a TArray> to map StaticMeshActors to indices in an array of arrays of materials, but I've got a feeling it can be done with some GC control per copied material.

I think AddToRoot() could be the way to go, but I need to call RemoveFromRoot() before play in editor ends. I tried calling it in BeginDestroy(), but the crash still occurs.

avatar image ue4-archive ♦♦ STAFF Mar 11 '14 at 02:39 AM

Unresolved

"Even if this isn't the best way to go about doing that, I'd still be interested to know how to solve this issue with TMaps."

Well then I cant help you much, since TMaps are not working with UProperty(),

good luck with this!

Hope Epic has way to address TMaps + UProperty()

Rama

avatar image sytelus Jan 12 '18 at 02:20 AM +

I needed to use TMap because I'm using sparse array.

(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