In the .cpp and If I don’t check that all of this exist, the editor crashes.
In the constructor:
if (GetOwner()){
if (GetOwner()->GetRootComponent()){
UE_LOG(LogTemp, Log, TEXT("RootComponent exist"));
interactText->AttachParent = GetOwner()->GetRootComponent();
}
}
The set-up of the interact text class.
/*
Method setting the default data for the interaction system interact text.
*/
void UInteractionSystem::setInteractText(){
// Create the object and make it visible
interactText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("InteractText"));
interactText->SetHiddenInGame(true);
interactText->SetText(LOCTEXT("InteractText", "Interact"));
// Default to black color
interactText->SetTextRenderColor(FColor(0, 0, 0, 255));
// Font size
interactText->SetWorldSize(72);
// Align to center
interactText->VerticalAlignment = EVerticalTextAligment::EVRTA_TextCenter;
// Put the text over the actor head.
interactText->AddLocalOffset(FVector(0, 0, 150));
interactText->RegisterComponent();
}
When is setInteractText() being called? It appears that you are doing interactText->AttachParent prior to the CreateDefaultSubobject<> call. This would cause a crash since interactText is NULL when AttachParent is set. Moving interactText = CreateDefaultSubobject(TEXT("InteractText")); to the constructor above the other code you posted should help.
Can you try putting your code inside a SceneComponent class rather than an ActorComponent class? SceneComponent inherits from ActorComponent and also has a transform to represent where it is in the level. Also, can you describe exactly how it isn’t working for you? Are you getting compile errors or is the text just not showing up in the editor or is it something else?
The problem isn’t a crash or compile error.
It’s simply that the deffered attach using the stuff->attachParent isn’t working inside the editor or ingame except if I attach the components dynamically at the BeginPlay().
Actually, this did the trick better. My previous answer could still crash the engine.
UInteractionSystem::UInteractionSystem()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
bWantsBeginPlay = true;
PrimaryComponentTick.bCanEverTick = false;
setInteractText();
// Set delegates for range
interactSphere->OnComponentBeginOverlap.AddDynamic(this, &UInteractionSystem::playerEnterRange);
interactSphere->OnComponentEndOverlap.AddDynamic(this, &UInteractionSystem::playerExitRange);
if (GetOwner()){
// Depending on if a Root Component exist, assign or attach the component to Root Component
if (!GetOwner()->GetRootComponent()){
GetOwner()->SetRootComponent(this);
} else {
this->AttachParent = GetOwner()->GetRootComponent();
}
interactText->AttachTo(this);
}