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"

[Closed] How can I convert a UObject to a derived type in a Factory Reimport?

I've made a new UObject type, UCustomMaterialInstanceConstant, that inherits from UMaterialInstanceConstant. I have also set up a UFactory and implemented the IReimportHandler interface to create these classes on import and reimports of a custom file extension. The system works until I need to import a new Custom material instance into a content browser location where a vanilla material instance lives. I'd like to have the (re)importer automatically convert the UMaterialInstanceConstant to my new class type. I have not been able to figure out how to do this. Currently, I"m attempting to do the conversion step with the following code.

 EReimportResult::Type UCustomMaterialInfoFactory::Reimport( UObject* Obj)
 {
     auto Result = EReimportResult::Failed;
     if (auto CustomMatConst = Cast(Obj))
     {
             // Do regular FactoryCreateText() behavior here...
             result = EReimportResult::Success;
     }
 
     // Support upgrading vanilla mat instances to custom mat instances
     else if (auto MatConst = Cast(Obj))
     {
              // What do I do here?
     }
     return Result;
 }
  

I've attempted the conversion by:

  1. Deleting the old asset and creating a new asset of the correct type in its same package path.

  2. Creating the new custom type asset and performing a ConsolidateObjects() to collapse the old asset onto then ew one.

  3. Creating a transient asset of the new custom type, deleting the old asset, and calling DuplciateSingle onto the old asset's package path.

Ultimately, none of these options have been successful because the calling function of UFactory::Reimport(UObject* Obj) always interacts with Obj afterwards. Deleting or mishandling the UObject in any way causes a fatal crash as soon as Reimport() finishes. What are my options here? Should I be approaching this from a different way?

Product Version: Not Selected
Tags:
more ▼

asked Feb 07 '17 at 09:56 PM in C++ Programming

avatar image

Answers.Archive STAFF
1.9k 208 316 688

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

The question has been closed Feb 07 '17 at 10:01 PM by AndrewHurley for the following reason:

The question is answered, right answer was accepted


1 answer: sort voted first

Hi Eric,

Do I understand correctly you're trying to replace these classes in an existing asset? If so you should look at ActiveClassRedirects in DefaultEngine.ini (look for examples in BaseEngine.ini). This will allow you to replace classes when the asset is being loaded.

more ▼

answered Feb 07 '17 at 09:57 PM

avatar image

Answers.Archive STAFF
1.9k 208 316 688

avatar image Answers.Archive STAFF Feb 07 '17 at 09:57 PM +

Correct, I am trying to replace existing assets. This is an interesting solution. I tried adding this line to my DefaultEngine.ini and the editor wouldn't start.

 ActiveClassRedirects=(OldClassName="MaterialInstanceConstant",NewClassName="CustomMaterialInstanceConstant")

It's worth noting that my CustomMaterialInstanceConstant class is defined in a plugin and might not be available during the class redirect phase. Can you confirm this?

I'm also not interested in replacing every instance of the class with my own. I'd prefer to keep it on-demand and not make a global change to assets across the project. Are there other solutions?

avatar image Answers.Archive STAFF Feb 07 '17 at 09:57 PM

Oh, yeah, if you try and replace a low level class like this everywhere it's not going to work. I think commandlets would be best to achieve this. I'd make a new commandlet that loads only the package file summary of each package inside of the specified folder and if it contains the class you want to replace, replace it in the linker table just like LinkerLoad code would do it and load the rest of the package and resave it. PkgInfo commandlet is a good place to start - it can load the package file summary and linker tables as a separate step.

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

Follow this question

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

Answers to this question