Download

Adding a sphere component to an actor component

Hello everyone,

I have an actor component which is responsible for establishing a connection with other actors within a certain radius. While the player is placing the actor in the world, it will draw a preview to the other actors it will connect to if the player decides to construct it there. To accomplish this, I create a sphere component in the constructor of the link component, and then subscribe to the appropriate events when the game begins:



ULinkComponent::ULinkComponent()
{
    SphereComponent = CreateDefaultSubobject<USphereComponent>(FName("SphereComponent"));
}

void ULinkComponent::BeginPlay()
{
    Super::BeginPlay();

    SphereComponent->AttachToComponent(GetAttachmentRoot(), FAttachmentTransformRules::SnapToTargetNotIncludingScale);
    SphereComponent->OnComponentBeginOverlap.AddDynamic(this, &ULinkComponent::OnComponentBeginOverlap);
    SphereComponent->OnComponentEndOverlap.AddDynamic(this, &ULinkComponent::OnComponentEndOverlap);
    SphereComponent->RegisterComponent();
}


Note that


GetAttachmentRoot()

is a private function I created in the link component to retrieve the root component from the owner.

While this works perfectly fine, the whole approach feels odd to me. The SphereComponent does not show up as a component in the Blueprint editor, and because I had to set the SphereComponent to VisibleAnywhere in order to have the radius editable, a lot of properties shared between the actor component and the scene component show up twice in the list of properties.

Is creating scene components from actor components really the proper way forward? Any insights are greatly appreciated!

Thanks!

Components aren’t really designed to be the children of other components, they’re supposed to only be children of actors. You will run into quite a few issues trying to create them without a valid Actor outer.

Hi TheJamsh,

Thanks for the quick response! I already had a feeling I wasn’t solving this as intended by the engine. So what would actually be the proper way of having an actor component that subscribes to a sphere component? I see that the engine has a FComponentReference but it sounds like a very brittle construct. I would prefer to have a designer add a single component to an actor that also creates the sphere component, rather them have them add a component and somehow magically have them know it requires a reference to a sphere component they also need to add themselves. My problem with the latter solution is that the component will no longer really be self-contained since it can’t function without an outside reference.

Thanks!

If anyone has any opinions on this, I would love to hear! I’m still looking for the best way to move forward.

Thanks!

I’ve tried going down the FComponentReference route but I feel it is too brittle of a construct, and requires too much hassle on the side of the designers. I am back to where I started in the original post. If there is anyone who has a similar experience, I would love to hear because I am still unsure what the proper way forward is.

Thanks!

Why don’t you just handle it in the class of the actor that is being placed? You can just have the sphere component (or manual sphere traces) and run the logic there. Alternatively you could also create a separate class for the unplaced/unconstructed actors since I’m guessing those behave a fair bit differently.

In situations like this I’ve used OnAttachmentChanged() or OnChildAttached() and GetParentComponents() or GetChildrenComponents() to register withing my custom component whatever the designer attached to it (or run code when it was attached to a parent of certain class) since we can’t create a default component from another Component’s class constructor and I didn’t know where or to what the designers would attach my custom component to.

Thanks for the response! They are greatly appreciated. I finally managed to get it working to my satisfaction by exposing the parameters I want designers to influence and creating the collision component in BeginPlay. It won’t show up in the editor, but at least it doesn’t feel like I am hacking and works perfectly.

Looks like an old forum, but for anyone in the future, I came across a similar thing I was trying to setup. I just made my component inherent directly from the sphere component, so then I was able to use the sphere component functionality along with my custom stuff.

Late reply, but hopefully it’ll help someone else who stumbles across this forum in the future as well.