Create TArray dynamically in Unreal Engine

109 views Asked by At

Suppose I have a UObject class with a TArray saved as UPROPERTY. Is there a way to create TArray dynamically and then set Objects to a newly created array (see code below)?

UCLASS(BlueprintType, Blueprintable)
class SOME_API UClassA : public UObject
{
    GENERATED_BODY()

public:    
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    TArray<UObject*> Objects;    
};

NewObject seems to raise a compilation error when trying to create TArray

UClassA* ObjA = NewObject<UclassA>();
TArray<UObject*>* NewArray = NewObject<TArray<UObject*>>(); // this raises compilation error
ObjA->Objects = *NewArray;

Error:

Error C2039 : 'StaticClass': is not a member of 'TArray<UObject *,FDefaultAllocator>'
Reference C2039 : see declaration of 'TArray<UObject *,FDefaultAllocator>'
Reference C2039 : see reference to function template instantiation 'T *NewObject<TArray<UObject *,FDefaultAllocator>>(UObject *)' being compiled
          with
          [
              T=TArray<UObject *,FDefaultAllocator>
          ]

Can I create TArray with simple c++ new will this work? Will the Garbage Collector keep track of new array instead of the Objects array created in the constructor?

Edit: I intend to create both TArray and contained UObjects dynamically. And I want the UE Garbage Collector to see them. This is meant the to be the only place they are stored.

2

There are 2 answers

4
Ted Lyngmo On

You may use Add or Emplace to add elements to the TArray if UClassA inherits from UObject (which should also have a virtual destructor):

TArray<UObject*> Objects;
//...
Objects.Add(new UClassA);

If you also want to create a single TArray dynamically, you could store it in a std::unique_ptr:

#include <memory>
//...
std::unique_ptr<TArray<UObject*>> Objects;
//...
Objects = std::make_unique<TArray<UObject*>>();
7
Caleth On

NewObject<UClassA>() has already created a TArray<UObject*> with dynamic storage duration, as a member subobject of *ObjA. You don't need to new a second one.

The garbage collector does't deal with members, those are destructed by the destructor of the enclosing object.

If you want to fill a new TArray and then assign to ObjA->Objects, then you can use a local variable.