I have a weird problem with my actors. If I drag and drop my actors into the scene, the child components are following the parent just fine (here, it’s a health bar), but if I dynamically spawn them, then the health bar is at the origin of the world. The mesh spawn at the right location, only the health bar is at (0, 0, 0).
The mesh is created in the parent class but loaded in the child.
The health bar is created and affected in the parent class.
Constructor of the main class :
ASelectableActor::ASelectableActor()
{
// Set the replication ON
bReplicates = true;
// Create the mesh component and makes it the root
mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
mesh->SetCollisionProfileName(TEXT("BlockAllDynamic"));
RootComponent = mesh;
// Create the widget and attach it to the Root Component
static ConstructorHelpers::FClassFinder<UUserWidget> hudWidgetObj(TEXT("/Game/HUD/SelectableActorHUD_Widget"));
if (hudWidgetObj.Succeeded()) {
hudWidgetClass = hudWidgetObj.Class;
}
else {
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "SelectableActorHUD not found !");
hudWidgetClass = nullptr;
}
hudWidget = CreateDefaultSubobject<UWidgetComponent>("Widget");
hudWidget->SetWidgetClass(hudWidgetClass);
hudWidget->SetupAttachment(mesh);
hudWidget->SetWidgetSpace(EWidgetSpace::Screen);
hudWidget->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
hudWidget->SetDrawSize(FVector2D(100.0f, 5.0f));
hudWidget->SetVisibility(false);
hudWidget->RegisterComponent();
}
Ok so apparently my “hudWidget->SetupAttachment(mesh);” is doing jack sh*t.
The WHY and HOW
So after some deep research I’ve found out the reason behind all that :
On this really interesting link, you can see that the component initialization comes after the constructor, which means we may not be able to attach things together before the BeginPlay().
For that exact reason, I’ve attached my health bar to my mesh INSIDE the BeginPlay and set its relative location to (0,0,0). Now my health bar is correctly displayed on my actor.
Well hellloooooo thereeeeeee, I come from the FUTUREEEEEE!!!
No seriously though, you’ve saved me! Thank you for updating your post with your solution. I’m doing much the same thing where things of type BaseAbility are being spawned in the world. Some child type actors have an AnimationComponent where they are given a Flipbook (2d version of a mesh), but this would always render at world 0.0.0. The actor would be spawned in the right place, but when examining the instance, the mesh would have a magically calculated offset to always leave it at world origin no matter where it’s actor was. So thanks again!
I just did the same, but it didnt work for me with “SetupAttachment”. I had to use AttachToComponent with the FAttachmentTransformRules::KeepRelativeTransform parameter.
I came across two of your posts ! and u know what i love about them. that you figured out the answer and u posted it for others to learn !
i really appreciate it
Even further Futureman here: This post’s solution worked for me the attachment now happens in the constructor. Additionally I also added virtual void OnConstruction(const FTransform& Transform) override; in the .h file with this in the .cpp file: void ABLACK_Weapon_Master::OnConstruction(const FTransform& Transform) { Super::OnConstruction(Transform); }