2

The following code has been bothering me for a bit:

ARollingBall::ARollingBall()
{
    UStaticMeshComponent* sphere;
    sphere = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ball"));
    static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Engine/BasicShapes/Sphere"));
    sphere->SetupAttachment(RootComponent);
    if (SphereVisualAsset.Succeeded()) {
        sphere->SetStaticMesh(SphereVisualAsset.Object);
    }
}

Namely that I am hard coding a path. What if I decided I wanted to use a different object down the road? Imagine I had multiple pawns all hardcoded to use this asset. In cpp there is no easy way to change all these references. I had the bright idea to expose my mesh choice to blueprints to leverage Unreal's reference handling like so:

UPROPERTY(EditDefaultsOnly, Category = "References")
UStaticMesh * m_staticMesh;

However the following does not create a mesh when I inherit from this class with a blueprint and set the default mesh (m_staticMesh):

ARollingBall::ARollingBall()
{
    UStaticMeshComponent* sphere;
    sphere = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ball"));
    sphere->SetupAttachment(RootComponent);
    if (m_staticMesh) {
        sphere->SetStaticMesh(m_staticMesh);
    }
}

I'm using Unreal 4.21.2 both methods compile, but the latter fails to work.

Any suggestions on how to make the above function properly are appreciated. If you know of a better way to avoid hardcoding paths please let me know.

Jason Basanese
  • 660
  • 5
  • 16
  • Some testing showed that the `if(m_staticMesh)` conditional fails to pass. I don't understand why though given that I have set a default value in my blueprint subclass. – Jason Basanese Mar 06 '21 at 18:09

1 Answers1

2

Using Static Constructor Helpers is generally not recommended at all.

Composing an Actor of Components and utilizing Unreals Reflection system to expose those Components and their properties to the Editor to be modified in Blueprints is the ideal pattern.

/* Weapon Mesh. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Weapons")
UStaticMeshComponent* Mesh;

Marking a Component that is created during construction with VisibleAnywhere will cause it to appear in the Component Hierarchy within the Actors Component view after creating a child Blueprint of that Actor.

Component Hierarchy

You will then have access to modifying its properties such as the StaticMesh.

It is useful to know what the valid Property Specifiers are when working with UPROPERTY as well as all the Function and Class Specifiers and their MetaData.

Property Specifiers

DevilsD
  • 407
  • 5
  • 11
  • Thanks, for the tip. Here's a video from a tutorial series I'm making where I use the above method: https://www.youtube.com/watch?v=caG6N0mXhz0 Video has a link to the github with the code. – Jason Basanese Mar 08 '21 at 15:17