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"

Initialize object based off blueprint in editor

I'm trying to write an inventory/item system where a UItem holds item data like the name and the mesh, and then a AWorldItem has a reference to a UItem blueprint, a StaticMeshComponent, and modifies itself accordingly based off whichever UItem it is supposed to represent.

So I've got a blueprint class based off UItem called Item_Box and I have a blueprint class based off AWorldItem called WA_Box. I set up WA_Box to hold a reference to the Item_Box blueprint, and now I want to make it so that the StaticMeshComponent in AWorldItem has it's static mesh set to the mesh property in the Item_Box.

I thought this was straightforward, however the following code crashes the editor as soon as it compiles:

 AWorldItem::AWorldItem()
 {
     PrimaryActorTick.bCanEverTick = true;
 
     meshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ItemMesh"));
     RootComponent = meshComponent;
 
     const UItem* const test = itemClass->GetDefaultObject<UItem>();
     meshComponent->SetStaticMesh(test->GetMesh());
 }
 
 void AWorldItem::BeginPlay()
 {
     Super::BeginPlay();
 }

What I'm confused about, is that changing the code so that the mesh setting happens in BeginPlay(), as illustrated in the following code, works just fine. But I want the mesh to be changed before the game even starts, so I can see it in the editor. I'm not sure how to do that.

  AWorldItem::AWorldItem()
  {
      PrimaryActorTick.bCanEverTick = true;
  
      meshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ItemMesh"));
      RootComponent = meshComponent;
  }
  
  void AWorldItem::BeginPlay()
  {
      Super::BeginPlay();
 
      const UItem* const test = itemClass->GetDefaultObject<UItem>();
      meshComponent->SetStaticMesh(test->GetMesh());
  }

I am not getting any sort of crash log from the editor. It says I don't have the debug symbols. In order to start the project back up without crashing, I have to remove the GetDefaultObject() line and build the solution from Visual Studio. What am I doing wrong?

Product Version: UE 4.12
Tags:
more ▼

asked Jul 11 '16 at 01:44 AM in C++ Programming

avatar image

Dooskington
6 2 5

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

1 answer: sort voted first

What you want to do is to make your item class property as editable in the editor and then you should derive OnConstruct function and change the mesh in it.

What is going to happen is the actor will trigger construction script every time the item class property changed and then your mesh changing code will automatically run.

Maybe something like this:

 UCLASS(Blueprintable)
 class AWorldItem : public AActor
 {
     ...
 
     void SetItemClass( TSbclassOf<UItem> InItemClass )
     {
         ItemClass = InItemClass;
         UStaticMesh* StaticMesh = ItemClass ? ItemClass->GetDefaultObject<UItem>()->GetMesh() : nullptr ;
         meshComponent->SetStaticMesh( StaticMesh );
     }
 
     virtual void OnConstruct( const FTransform& Transform ) override
     {
         Super::OnConstruct( Transform );
         SetItemClass( ItemClass );
     }
 
 protected:
 
     UPROPERTY(EditAnywhere, Category="Item")
     TSubclassOf<UItem> ItemClass;
 
         ...
 };
 
 

more ▼

answered Jul 11 '16 at 01:38 PM

avatar image

Heapcleaner
541 15 5 19

avatar image Dooskington Jul 11 '16 at 02:22 PM

This works great, thanks! Let me just note that the function is named OnConstruction() in the current engine version.

I have some questions though... What's the deal with the constructor, like what is the difference between that and OnConstruction()? You setup the components in the constructor, so I assumed you would set every other Actor default in there. Also, why the 'Blueprintable' key on the UCLASS()? I don't have that and mine works just fine, and I'm able to make a blueprint of it.

avatar image Heapcleaner Jul 11 '16 at 02:35 PM

Ah yes, sorry, it is OnConstruction.

There are many points in which we can initialize an object, the class constructor is usually where we want to create various sub-default object or specifying values of native properties. There is also PostInitProperties where we can initialize some properties after cdo has been copied, and then we have PostLoad where we can change the value of some properties after the object has been loaded.

OnConstruction is special to an Actor (Object does not have it), along with PostInitializeComponents. The safest and easiest way to initialize an actor after one of its properties has been changed in the editor is to add it in OnConstruction, although not all properties will trigger the construction script (e.g Transform will not be trigger construction script for non blueprint actor), you can also reconstruct the actor manually ( I believe it is RerunConstructionScript, sorry my current laptop doesn't have UE4)

As for the Blueprintable, that's not necessary, most class modifiers are derived from its parent, including Blueprintable, it's just a habit of mine so that by just looking at the class modifiers I know that it can be made into blueprint, and for some cases where I don't want user to use this class as parent class for a blueprint then i just add Non in front of it.

avatar image Dooskington Jul 11 '16 at 02:38 PM

This is very useful information. Thank you!

(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