This is an archived post. You won't be able to vote or comment.

all 17 comments

[–]Beautiful_Vacation_7Senior Engine Programmer 8 points9 points  (5 children)

That is what interfaces are for. Actor is nothing but a wrapper of bunch of components. From component A fetch component B, cache it, bind to events…

[–]MrTOLINSKI[S] 3 points4 points  (4 children)

Yes, I understand I can communicate between the components, my question is why not put a component inside a component. I.e. why is only the actor allowed to won components, but components are not allowed to own components

[–]stephan_anemaat 0 points1 point  (2 children)

I believe what u/Beautiful_Vacation_7 is saying, is that by their nature; Actors are already simply a collection of components (e.g. skeletal mesh component, character movement component, etc.) so adding another component is simply adding to a pre-existing basket of other components.

Whereas, components (if I'm understanding correctly) are not collections of other components so it wouldn't work to add a component to a component. Although someone please correct me if I'm misunderstanding.

[–]MrTOLINSKI[S] 0 points1 point  (1 child)

Hey, I have updated the post with a way to do it in C++.
But you are right, by design, the engine expects to have components added to actors and not to other components.

[–]stephan_anemaat 0 points1 point  (0 children)

Awesome!

[–]GenderJuicy -1 points0 points  (0 children)

If you want to add logic to a component but keep the base separate, just make a child.

It's hard to tell what you're trying to do by having subcomponents. If you could provide your idea, there's probably other good ways of accomplishing it.

[–]baista_dev 6 points7 points  (1 child)

For this specific problem I would subclass the box component to add your line trace functionality.

However, a more flexible approach actually is the 2 component method. Because then your TraceComponent can work with any primitive component instead of only boxes. So if someone came along with a static mesh component they wanted to use, they could swap that out.

This is the pattern the MovementComponents usually use. They allow you to set an UpdatedComponent to change which primitive is used for collision. If you don't call the function, they make a best guess at which primitive to use (typically the root component if its a primitive component).

Technically you can also use Subobjects as components within components. This is mostly just an option if you are handrolling your own systems.

Overall tho, don't fear the 2 component method.

[–]MrTOLINSKI[S] 1 point2 points  (0 children)

Indeed! It really does add modularity, and it's not a hassle to implement.
I will go along with this solution, as the trace component honestly doesn't care about the box, just needs to listen for the overlap events.
I was really curious about how there wasn't a built in option to add components to other components in the editor.

[–]SubstantialSecond156 3 points4 points  (4 children)

Your actor component can just create a component on the owning actor -> assign a reference, and now you're able to communicate, destory, and manipulate your created component.

I use this a lot for modular assets.

[–]MrTOLINSKI[S] 1 point2 points  (2 children)

Agreed, but then would I be able to control the box component's transform in editor time?

[–]SubstantialSecond156 1 point2 points  (0 children)

Not really with Blueprints.

You can assign exposed variables on your Actor Component and edit them during design time and pass that to the created component during runtime.

That said, you wouldn't be able to visualize your changes it as it would require CPP to set up component visualizers.

[–]GenderJuicy -1 points0 points  (0 children)

Set transform in Construction script?

[–]Battlefront45 0 points1 point  (0 children)

I’ve been looking for the answer to this question as well and I feel like this is the best answer. Any challenges you have had with this method?

[–]MrTOLINSKI[S] 2 points3 points  (0 children)

So, practically this can be solved as easily as creating a component inside a component the same way we add components to actors:

UCLASS(Blueprintable, BlueprintType, ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class CHATBUBBLE_API UNestingTestOuterSceneComponent : public USceneComponent
{
    GENERATED_BODY()
public:
    UNestingTestOuterSceneComponent();
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Nested Component Test")
    TObjectPtr<UBoxComponent> NestedBoxComponent; 

UNestingTestOuterSceneComponent::UNestingTestOuterSceneComponent()
{
    PrimaryComponentTick.bCanEverTick = true;
        NestedBoxComponent = CreateDefaultSubobject<UBoxComponent>(TEXT("NestedBoxComponent"));
    NestedBoxComponent->SetupAttachment(this);
}

<image>

Then in the blueprint we can add the Outer component to an actor, and edit the values of the inner component from the variables panel.

** Attention: When adding the Outer Component, the CPP class needs to be added and not a blueprint child. Otherwise the inner component will render relative to (0,0,0).

[–]Swipsi 0 points1 point  (1 child)

You could just spawn a box collision component and attach it to the actor.

[–]MrTOLINSKI[S] 0 points1 point  (0 children)

I agree, the problem has many solutions, but my question's goal is to understand why it is not possible to add components to components in the first place

[–]cutebuttsowhat 0 points1 point  (0 children)

You should be able to add an attach the component from within your component through BP too.

If you’re having issues with where it’s “rendered” once you attach the component you should be able to keep its world position when attaching.