1
\$\begingroup\$

I struggle to understand best practices regarding composition and inheritance for Actor Components in Unreal Engine 5. Concretely, I want to build a base class, say Interactable that handles basic functionality of interactable items in the level. E.g. it detects collision, creates a prompt saying "Press [E] to interact", and then triggers an event or function when this happens. Subclasses can then implement this concretely.

Now, when I implement Interactable as an Actor, it's all easy. I can add a Box Collision to the scene root and listen to events triggered by it. However, this seems like a bad practice, because an Actor then always ever be either Interactable or, say, Destructible.

It occurs to me that Interactable should rather be an Actor Component instead. However, an actor component can neither have nor be a collision box. They cannot have a collision box because components cannot have components. I feel it should be possible that they can be a collision box, but at least for Blueprints I don't see a way to achieve that. It seems the superclass should be something like UBoxComponent. However, this is not available from the "New Blueprint" dialog. (Why?) The lowest ancestor is PrimitiveComponent, but that, too, cannot be selected as a blueprint parent class. (Why?)

The only ways out I see are:

  • Require that any Actor who wants to use the Interactable component also define a collision box. Then, in the component code of Interactable I can look it up and register events with it. This puts needless burden on the user and seems very odd.
  • When the Interactable component is constructed, add a collision box to the parent actor programmatically. This seems equally odd to me, and again is not user friendly because it will not be visible in the UI.
  • Use C++ I guess? I'd be fine with that in principle, but it seems this task is so simple that it lends itself well to the Blueprint concept, and I'd be surprised if this really only works in C++.

Is there a better one?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

ActorComponents have no transformation, so they can't have physical presence. SceneComponents, however, have a transformation, and PrimitiveComponents derived from SceneComponent have physical (collision) presence.

There are a few ways to use this in an object fashion:

  • You could derive your Interactable from something like the Box collision component. This is classic "inheritance" OO. I don't like it much, but it's there.
  • You could also have a reference that's set at construction time -- you don't make the component yourself, you get configured with the component to use for presence. That way, both Destructible and Interactable could use the same Box. This is modern "delegation" OO, and tends to lead to fewer "diamond inheritance" problems.
  • Finally, you can scan your actor for collision components, and configure yourself to use those at runtime. This is the dynamic "dynamic discovery" flavor of OO, which is super flexible, but with that flexibility comes a much harder time to debug things when they go wrong.
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .