Best way to handle interaction with different actors/components

Hello,
I have my own interaction component that belongs to the default player. Whenever I click on certain objects, I want some action to happen depending on the clicked object.
As of now I’m using what I’m sure is a really dirty strategy: for each actor I want to interact with, I’m creating a component to perform a specific action, and after getting the result from LineTraceSingleByObjectType I differentiate basing on the actor name. For example:



if (ActorName.Equals("SM_Lever_24"))
{
    ActorHit->FindComponentByClass<ULeverPullComponent>()->ActivateLeverPull();
}
else if (ActorName.Equals("SM_Lock_Key_38"))
{
    //...
}
else if  (...)


Of course, this has to change.

Another solution that I found about is creating custom classes inheriting from AActor for each actor I want to interact with, write the logic directly in there (thus no component) and then differentiate by casting. For example:



AMyLeverClass* LeverActor= Cast<AMyLeverClass>(ActorHit);
if (LeverActor)
{
    LeverActor->PullLever();
    return;
}

AMyKeyClass* KeyActor= Cast<AMyKeyClass>(ActorHit);
if (KeyActor)
{
    KeyActor->Pick()
}

...


This solution is a bit more general but still kinda ugly…

Last solution I thought about is using LineTraceSingleByChannel / LineTraceSingleByObject (still have to study them so I don’t quite get the difference). creating a custom channel that I will assign to each of the actors I want to interact with, but more importantly I will create a custom base class which will have some kind of function “ProcessInteraction()” and all the actors I want to interact with will inherit from this, implementing their own version of ProcessInteraction.

I’d like to have opinions from people more skilled than me, on if my last solution is good, or if there are any other more standard/stable/efficient solutions. Thanks in advance.

Use Interfaces to process generic events.

I usually don’t use interfaces to be honest. What I do for stuff like this is I create a base class for interactable objects, and then inherit from that class. You can put a virtual function like BeginInteract() in the base class and override it in the inherited classes. I like doing it this way because I usually put other variables in the base class as well, such as a bool to check if the object can recieve interact input or not.

In Unreal C++ you can put all variables and functions in the interface definition.

So take any class, put “: public IInteractiveObject” after the class declaration, and you now have all interactive object functionality regardless of base class.

Then you are limited to using that base class for all interactable actors. How about in the future you want to interact with a pawn? or something?