Hi, welcome to the community.
I see that you have many traces around the system, you scan interactables, check them, prioritize them etc. There is couple of places I see you do some logic which doesn’t makes too much sense to me
Over here you are checking a current interaction then if not valid you setting a new one which wouldn’t be valid imo.
This is generally not sure how your logic works or works at all but, you don’t have to overcomplicate it actually.
1- You have a player, player has some actors around them which are interactable.
2- You scan these and prioritize which one of them is player trying to interact and can interact.
3- If something trying to be interacted and can be interacted with all conditions you send an event to that actor.
I put a tutorial simple but extendable interaction system over here a while ago, think would be very beneficial for you. It also explains how to make additional rule systems with ease on this system design like: “Rule : Not Blocked” , “Rule: Distance” etc
However if you want to continue on your existing system (Which is ok), I would recommend.
-
You always scan the objects around the player. Add to an array unique “InteractablesAroundMe” if its not already added. They also need to be removed so raather than traace an overlapping sphere can be nice. So make sure you tracking right amount and unique items.
OnOverlapBegin-> DoesImplementInterface->IsAlreadyAddedToArray(Find)-> If not add
OnOverlapEnd ->DoesImplementInterface->RemoveFromArray -
You can always trace infront of player after that if you like. OnTick->SphereTrace(CameraDir)->OnHit->FindItem(Actor)-> NotEqual (-1) → SetCurrentInteractable
-
Still we don’t show widget etc we scanned interactables, check if player is looking to one of them and prioritize it but not yet showing widget. On widgets many things need to happen, like if interacted it should close, if player is away it should close, another one opens again should close. So first be sure that only one and one interactions is set to CurrentInteractable.
The trick is always know what you are interacting with and what widget you are showing. That would avoid creating multiple widgets or loosing track of the already created ones.
- Showing the Widget : You can have couple of approaches.
1- You can have one widget and if there is a valid CurrentInteractable you show it and position to whatever actor position is. On this one you have to track the state of the target aswell sometimes. bAlreadyInteracted. If something already interacted we don’t show widget even its valid.
2- You can spawn instance one one widget and set a variable inside as WidgetCurrentInteractable. When this WidgetCurrentInteractable(notequal) *CurrentInteractable then it means player changed camera or did something else, you can assume that this widget no longer needed and remove it from parent inside the widget. So it acts like standalone. Widget say : If I am equal to players current interaction, i will stay, if not i will go.

