Announcement

Collapse
No announcement yet.

How to use NewObject with a variable for typename?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    How to use NewObject with a variable for typename?

    Is there a way to create a new object where the template/typename can be determined dynamically?

    Suppose I have a parent class (ParentClass) with two child classes (ChildA and ChildB). I want to be able to create a new object, but won't know until runtime whether it's going to be a ChildA or ChildB. What I want is to do something like this:

    Code:
    UClass* ClassToCreate;
    
    if (bSomeBool)
    {
        ClassToCreate = ChildA::StaticClass();
    }
    else
    {
        ClassToCreate = ChildB::StaticClass();
    }
    
    ParentClass* FreshObject = NewObject<ClassToCreate>();
    But this doesn't work. The <> are not expecting a UClass* to be put between them. But I cannot figure out how to vary what goes between them. Is there a way?

    #2
    It needs to be:

    Code:
    ParentClass* FreshObject = NewObject<ParentClass>(ClassToCreate);

    Comment


      #3
      Code:
      UPROPERTY()
      TSubclassOf<UClassToCreate> ClassToCreate;
      Code:
      if (!ClassToCreate->IsValidLowLevelFast()) {return;}
      
      auto FreshObject = NewObject<UClassToCreate>(this,ClassToCreate->GetFName(),RF_NoFlags,ClassToCreate.GetDefaultObject());
      | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

      Comment


        #4
        Awesome, thanks guys!

        Comment


          #5
          I can't get either of these to work actually, so I must be doing something wrong.

          First answer (TheJamsh):

          Code:
          UClass* ClassToCreate = ChildB::StaticClass(); 
           ParentClass* FreshObject = NewObject<ParentClass>(ClassToCreate);
          This just produces an object of class ParentClass.


          Second answer (BrUnO XaVIeR):

          Code:
          TSubclassOf<ParentClass> ClassToCreate = ChildB::StaticClass();
          if (!ClassToCreate->IsValidLowLevelFast()) { return; }
          auto FreshObject = NewObject<ParentClass>(this, ClassToCreate->GetFName(), RF_NoFlags, ClassToCreate->GetDefaultObject());
          This throws an exception on the final line.

          Am I doing something wrong here, or is the code wrong?

          Comment


            #6
            Your "ParentClass" isn't an UObject Type and doesn't have any Default Object template thus there is no point using it with the UProperty System.

            I know because there's no "U", "F" or "A" prefix there...
            It's fundamental to understand UProperty and UObjects before you do any work in Unreal:

            https://www.unrealengine.com/en-US/b...tem-reflection

            Many people try to just use regular C++ routines in game classes, instead of making use of UProperty System, and it all ends as a hugh mess.
            | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

            Comment


              #7
              Actually it is derived from UObject. The code I've posted is just an abstracted form of what I'm using to make things simpler. My classes are not actually called ParentClass, ChildA and ChildB! Granted, I probably should have written UParentClass, but I was just trying to convey the concept of parent/child classes. Sorry for the confusion.

              Comment


                #8
                Then the issue may be many different causes; how ChildB was built, where you assign to ClassToCreate, where you're calling NewObject (or DefaultSubobject) from, etc.
                If "this" static pointer isn't a world member UObject, then you most likely get a crash/exception, as it's meant to be "outer" of the new object you've just created.
                | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                Comment


                  #9
                  Hmmm... I think you're right it's to do with the "outer". Investigating. Thanks for helping!

                  Comment

                  Working...
                  X