11

I found about four different ways to instantiate the object, but not sure if my understanding is clear.

  • NewObject<T>() function used when we want to make at the instance of UObject. For example, it can be any ActorComponents.

    USomeComponent sc = NewObject<USomeComponent> (class);

  • ConstructObject<T>() one more way to init UObject...

  • CreateDefaultSubobject<T>() but using this one function we also can create an instance of any class inherited from UObject.

  • SpawnActor<T>() used for instantiating an object of AActor class.

So first question: What is the difference if we can use these functions for one purpose? How and when and why we need to use any of them?

whenov
  • 684
  • 1
  • 8
  • 18
raviga
  • 245
  • 2
  • 10

1 Answers1

17

To understand the difference between these functions, you need to remember that the object model in Unreal Engine is based on object prototypes, very much like in JavaScript. Each UClass is associated to a default instance of the associated UObject class, called the Class Default Object (CDO), which is allocated first and then constructed, only once, via the class constructor when the engine is initialised. The CDO acts as a template from which all other instances of the class are copied, and the constructor is never called again.

This means class constructors cannot contain any runtime logic, and should only be used to initialise the CDO and its properties. If the class contains any subobjects, like actor components, these must do the same, so their own default objects must be constructed first. The actual instantiation of the object must then be deferred, after the engine has initialised, so that every time a new instance of the class is requested to be created by normal gameplay code, the parent object and all of its subobjects are instantiated from their respective defaults.

So, the multiple ways of creating objects are necessary to handle all the different scenarios where an object may be created.

  • UObject::CreateDefaultSubobject is only callable in a class constructor, and takes care of creating an instance of the CDO of the subobject's class, setting its outer class as the caller object, among other things. The created object then becomes the default object for the property when its object class is instantiated.

  • NewObject<T> is the function normally used to instantiate objects after engine initialisation, during normal gameplay. It provides several convenience overloads to handle most scenarios.

  • UWorld::SpawnActor<T> is a convenience method to spawn actors in a level with the specified location and rotation, spawn collision settings, and checks to ensure it's a spawnable actor class, and is nothing more than a wrapper of NewObject<AActor>.

  • ConstructObject has been removed in favour of NewObject.

I recommend checking the engine source code for more information, especially UObject/UObjectGlobal.cpp and UObject/UObjectGlobal.h in the CoreUObject engine module. Internally, all these function ultimately call (as of 4.24) StaticConstructObject_Internal, which handles the actual object creation.

Rei
  • 323
  • 2
  • 7
  • So, using `CreateDefaultSubobject()` or `NewObject()` in very general is just a philosophy? Kind of rules what to use inside the constructor and outside? – raviga Feb 03 '20 at 08:43
  • 1
    Replicating `CreateDefaultSubobject` by using `NewObject` is quite complex, as it does a lot of things for you. Check the source for the former and you'll see why it's so convenient. But yes, the rule of thumb is, `CreateDefaultSubobject` in class constructors, `NewObject` otherwise. – Rei Feb 03 '20 at 12:30
  • By the way, I incorrectly state that the constructor registers components, but in fact these are registered when the actor is instantiated, not when the class is created. I'll edit it out. – Rei Feb 03 '20 at 12:34
  • got it. I will make a source review. Thanks. – raviga Feb 03 '20 at 12:51
  • btw, maybe you have some resources except of source, where I can deep into CDO. – raviga Feb 03 '20 at 12:55
  • A good start is https://docs.unrealengine.com/en-US/Programming/UnrealArchitecture/Objects/index.html. I am not aware of any other official resources with this information, but if I find some good article I'll add a new comment. This one may also be useful: https://docs.unrealengine.com/en-US/Programming/UnrealArchitecture/Objects/Optimizations/index.html – Rei Feb 03 '20 at 13:12