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"

Initiliazing UObject as UProperty in inherted class of ACharacter

Hello for all! I've implemented class, that inherited from UObject. I want to add an instance of it to another class as UProperty field. I know that it must be pointer and I know that it must be initialized by NewObject. But I can't figure out why this field is not valid in Blueprint if I initialized it in constructor. But this field is valid, when I initialized it in event BeginPlay.

Class inherited from UObject

 UCLASS(Blueprintable,  BlueprintType)
 class MYPROJECT3_API UCInventory : public UObject
 {
     GENERATED_BODY()
 public:
     UCInventory();
 };

 UCInventory::UCInventory() : Super() {}


Class that contains instance of above class

 UCLASS()
 class MYPROJECT3_API ACBaseCharacter : public ACharacter
 {
     GENERATED_BODY()
 
 public:
     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = General)
     UCInventory * inventory;
 }
 
 ACBaseCharacter::ACBaseCharacter(const FObjectInitializer& ObjectInitializer) :Super(ObjectInitializer)
 {
     inventory = NewObject<UCInventory>();
 }
 
Product Version: UE 4.9
Tags:
more ▼

asked Dec 12 '15 at 08:27 AM in C++ Programming

avatar image

ANtlord
13 2 4 8

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

2 answers: sort voted first

Try CreateDefaultSubobject when called in the constructor, see this question for clarification. e.g.

inventory = ObjectInitializer.CreateDefaultSubobject(this, TEXT("Inventory"));

NB: You should pass in this in the outer when you use NewObject so it won't be garbage collected, unless you want to create a temporary variable. e.g.

inventory = NewObject(this);

more ▼

answered Dec 12 '15 at 12:25 PM

avatar image

getnamo
726 36 15 42

avatar image ANtlord Dec 12 '15 at 01:39 PM

When I try to pass this to NewObject, I get a segfault. Something wrong?

I've tried create by ObjectInitializer.CreateDefaultSubobject(this, TEXT("Inventory")); it works fine. I've read answer, that you've pointed, but I want to clarify. Will be object, created by ObjectInitializer::CreateDefaultSubobject, under GC?

avatar image getnamo Dec 13 '15 at 10:25 AM

Yes CreateDefaultSubobject + UProperty will ensure the variable remains available for the lifetime of the parent object.

Not sure why you're segfaulting, perhaps its the custom constructor you've made. You shouldn't need to define one as GENERATED_UCLASS_BODY() will make the default

 UCInventory::UCInventory(const class FObjectInitializer& ObjectInitializer)
     : Super(ObjectInitializer){
 }

available

avatar image ANtlord Dec 13 '15 at 01:07 PM

Ok, problem has been solved, but I'm not sure, that GENARATED_BODY will make by default. I've comment it, and I've got compilation error, which contains this Expected a GENERATED_UCLASS_BODY() at the start of class

avatar image getnamo Dec 13 '15 at 01:13 PM

Try using GENERATED_UCLASS_BODY() instead of GENERATED_BODY()

avatar image ANtlord Dec 13 '15 at 02:02 PM

It makes no difference to me. I get an segfault. I can show log message. Fatal error: [File:D:\BuildFarm\buildmachine_++depot+UE4-Releases+4.9\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp] [Line: 2637] NewObject with empty name can't be used to create default subobjects (inside of UObject derived class constructor) as it produces inconsistent object names. Use ObjectInitializer.CreateDefaultSuobject<> instead.

I've tried to pass this and TEXT("Inventory") and it works. It works even with GENERATED_BODY. And it is valid. I can assume, that for instatiating objects of UObject, we need pass Outer and Name. E. g. NewObject(this, TEXT("Inventory")).

Thank you very much!

avatar image getnamo Dec 13 '15 at 02:35 PM

Yep the error message is consistent, the engine needs consistent object naming. Not sure why but I'm guessing it has to do with reflection and introspection.

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

Everything in constructor will be used in constructing Class Default Object, so you should not create any object in constructor, other then CreateDefaultSubobject which usally is used for component creation

But why not just?

 UCLASS()
 class MYPROJECT3_API ACBaseCharacter : public ACharacter
 {
     GENERATED_BODY()
 
 public:
     UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = General)
     UCInventory * Inventory;

     UPROPERTY(BlueprintReadWrite, Category = General)
     TSubclassOf<UCInventory> InventoryClass;

     virtual void BeginPlay() override;
 }
 
 ACBaseCharacter::ACBaseCharacter(const FObjectInitializer& ObjectInitializer) :Super(ObjectInitializer)
 {
 }

 void ACBaseCharacter::BeginPlay() {
      Inventory = NewObject<UCInventory>(this,InventoryClass);
 }

 

If you want to create default inventory, then consider creating array of UClasses (can be TSubclassOf) and fill inventory with items in array by spawning them and adding to inventory.

BeginPlay event was made for gameplay actor initiation, so don't be shy to use it for init stuff.

more ▼

answered Dec 13 '15 at 04:52 PM

avatar image

Shadowriver
37.2k 936 172 1116

avatar image ANtlord Jan 22 '16 at 10:55 PM

Thank you very much for explaination!

(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