How to check if an actor is occluded?

Hi!
For my interaction system, i’m using a sphere collision that registers if the actor overlapping it is the player. If yes, the we show a ui and let the player be able to interact with an object in multiple ways. the things is whenever the object is occluded by something else the player can still interact with the object.

Is there a good way to check if the actor is on the screen and not occluded?
the “was recently rendered” option doesn’t seem to work as it still give me a true value even when the object is occluded.

i don’t know what to do anymore because a sphere trace isn’t doing great either…

you can do a trace, perhaps on visibility or a specific profile
If the trace returns a blocking hit then that means that the interactable is blocked

you should probably add both the player and the object as ignored actors in the trace, and it should be fine

what do you think i should use as the start and end of the trace? i would personally use a " get socket location" from the character mesh as the start and get the camera rotation’s forward vector multiplied by 2500 added to the head location as the end. problem with that is: if i set the sphere trace’s radius to something that will fill the whole screen it just collides with the ground and nothing really works

Why would you have the trace be massive? I would probably do a line trace or a small sphere trace (maybe 10cm radius)

Start would be your character’s location, end would be the found interactable object’s location

This trace would be done after you find an interactable object, not used to find interactables

How you find interactables is another discussion, you can keep using what you’re using, or you can do another trace, perhaps on a specific “interactable” trace channel

i mean, i already use a sphere collision to check if the player is near an interactable object. I want the object to be interactable with only if the character is in the range of the interactable AND if the object is visible on the screen. so if the spheretrace radius is too small, it won’t register that the object is on screen and not occuded

But they’re 2 separate things

You can keep your sphere collision, but once your collision returns objects, then you trace from the player to the objects to see if they are not blocked by another object

Usually it’s also not enough to just say “if visible on screen”, because with 3rd person games, you can have a wall between the object and the player, but have both visible, because of the camera angle
Which is why you should just do a trace after you’ve found an interactable

yeah so basically what i want to do is once the player is in the interaction area, i start a trace to check if the object is in view of the camera but i’m struggling with that part

I see, you have the collisions on the interactables

But that shouldn’t be a problem, if the interactable detects a player actor, then it can trace like I mentioned before for blocking channels (perhaps Visibility or World Static/World Dynamic), and then either on tick or through a timer, trace regularly to see if the way is blocked
If not, it can notify the player to enable the interaction, and if it is, then do nothing
Once the state changes (Blocked/Unblocked), you can react appropriately to enable/disable the interaction and the UI

Alright I think I did well on this but here is how I managed to make the turn off when the object is occluded and disable the interaction logic.
Any opinion on the code and the ways I can make sure there is no error would be appreciated, I’m a beginner.


UI:

On Begin Overlap:

When the interaction area gets overlapped by the player, we set the “is overlapping variable to true”

Then we register the interactable using a BPI (basically just registers the interactable inside an array of all active interactables being overlapped and available to interact with).

After that, we set a bool variable called " has registered" to true and we check if the timer for the UI function is paused or not. If it is, we resume it. If not, we create it.


UI Function:

I want my interaction system’s UI to fade in and out of existence.

To achieve that, I try to check inside the timer if the interactable is blocked or not.

  • If it is, then I tell the interactable to try and hide it’s UI.
  • If it’s not, i’m checking if the opacity of the UI is totally opaque or not.
    -If it is then the " Is opacity less 1" variable will be set to false as it is fully opaque.
    -If not fully opaque, we set that variable to true.

Note: i’m also setting the “is opacity less 1” var manually to make sur it works as intended during the transitions.


The Trace:

Basically followed your advice but with a twist. doing it in the interactable object itself makes it way faster to update the variables of each interactable (from what i tried).

If the camera is blocked from the interactable, we set the “is blocked” to true and we get the value of that to tell if we should try to hide the UI.

As you will see, this “Try Hide UI” variable is very odd in the event tick but it works so i’m not complaining. (i have no idea why i did that but it seems to work perfectly, i think it made sense on a speed and logic aspect)


Event Tick

This is the biggest part i struggled to make work, i might have done lots of mistakes but here we go:

So, first we check if the player is overlapping.

  • If they are, we check if we should try to hide the UI.

    • If we should hide it, we check if the opacity of the ui is less than 1.
      -If it is less than 1, we check if the custom opacity of the ui is precisely 0.
      – If it is, we get the player character and from it we trace to check until the visibility changes and we also reset the opacity timeline because it should be totally invisible.
      – -if it is 1, we trace again to check if “is blocked” is true.
      -if it is blocked, make sure it will be trying to hide for the entirety of the timeline to make it go back to 0 by setting the try to hide to true no matter the outcome of is blocked as nothing will happen on false.
      – -If not then nothing happens on until the value changes to 0.
  • If we are trying to hide the UI but the opacity is fully opaque:
    – we trace again but this time we always try to get the blocked result.
    – -if it’s not blocked then we can reset the timeline for the transition.
    – -If it is blocked, we start playing the timeline to make it completely invisible and we set the is “opacity less 1” and “Try Hide UI” as this is the main logic behind the vanishing of the UI and it will lead to the rest of the logic on next tick.

That’s the logic to make the UI disappear but now we need to know when to make it appear.


If we are trying to show the UI: we also need to see if the opacity is less than 1

  • Is if it trying to show the UI and the opacity is less than 1, we trace to see if the interactable is blocked.
    -it it is blocked we set “Try Hide UI” to be sure about the next step (redundancy from the trace but it’s just to be sure)
    –if it is not blocked we play the animation to make it appear, setting “is opacity less 1” and try hide UI to false as it won’t need to be changed as long as it is fully opaque.

  • if the value of the UI’s opacity is supposed to be 1, we check if it is truly equal to 1 on the custom opacity.
    -If it is truly equal to one, we activate the trace again and on the value change, we make sure that everything is supposed to be the way it should be logic wise.
    -if it somehow isn’t we check the state of the visibility and set it manually


-If the player is not overlapping, we set the “try hide UI” value to true and reset the timeline of the fade in transition.


ON END Overlap

We basically check if the thing ending the overlap is the player . Based on the result, we set “is overlapping” to false, disable the variable that lets the player interact with an interactable, pause the timer and notify the bool for the timer pause that it is in fact paused, check if it is blocked and based on that we set the opacity of the UI accordingly when leaving.


CONTROLS

Basically, in the player character, the interaction action is bound to an event that checks if we can interact every time we press the right input.

  • On the event tick, i get a validated get of the highlighted interactable and check if it has registered first
    -If yes, then we check whether or not is is blocked and disable the ability accordingly.
    -if not, we disable the ability to interact

I have no idea if you’ll read this far but i’m kinda proud of myself for figuring it out in only 2 days as a beginner. as i said, any tips or advices are greatly appreciated!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.