Interaction System: Widgets not removing correctly when objects are close

Hello everyone!

I’m working on an interaction system using Blueprints. I have a scanner running on a timer (every 0.1 seconds) that detects interactive objects around the player using a MultiSphereTraceByChannel. Like in Resident Evil.

I also loop through the results and run a LineTraceByChannel (from the camera to the object’s center of mass) to check for walls/obstacles.
If the LineTrace hits an object (and not a wall), I trigger the “Show Widget” interface message.

Problem: Everything works fine when the objects aren’t too close to each other. However, when two interactive objects are close together, the following problem occurs: (When I open or close any one drawer, everything is fine, but when I open two drawers and close a second drawer, the widget in the second drawer isn’t deleted). And this problem isn’t just with this one actor, but with all those that are practically right next to each other.

I’d appreciate any advice on the correct display/hide algorithm.

Screenshots of my Blueprint are attached.

Thank you!

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.

1 Like

I changed the line tracing logic.
The line tracing goes to the actor. Check: is this the target actor?
YES: The path is free → Show the widget.
NO: (We’ve moved on to something else).
If NO (for example, actor2(from trace multi sphere) == actor1(from trace line), then check if they are interactive. YES, it’s just a neighbor → Show the widget.
NO, it’s a real wall → Remove widget.
P.S. I’m not a professional, and I don’t understand professional architecture. One widget for everyone, yes, I realized it should have been done this way from the beginning, and it should have been divided into components. I spent a lot of time figuring it out, but now it works. Thank you.

No worries, it doesn’t have to be professional, it can come to that stage with iterations. Glad that it worked.

1 Like