- Home /
How would I check if the player camera is looking away from an object?
I've been trying to figure out how one would figure out how to register when the object leaves the camera's view (Like a horror game where when you look away, an event with audio triggers). Although I'm unsure how to go about it. I got two options that I know of, and I'd like to know how others approach this as I'm dead certain that I'm going about it incorrectly.
Option 1: Raycast and register on walls/objects which are known to be out of sight(This would mean adjusting all the walls in a general radius to contain certain tags for every event, or scripts..., or layers...)
Option 2: Calculate the player cameras rotation where the center would be placed on the object(Every update since when the player moves around the calculation would change), then compare it to the player's actual rotation and when the player rotation goes out of pre-calculated bounds(Based off of the players distance + resolution? Resolution affects how wide or tall the camera is so...) it'd trigger the event.
Are there more practical options than these?
Answer by Ermiq · Nov 30, 2019 at 01:23 PM
Well, simplest way is to check the angle between camera forward vector and the vector that is the direction from camera to some position. And use camera FOV as a threshold. If the angle between is more than camera FOV, than object might be out of the player's view.
Transform objectThatShouldBeOutOfSight;
Vector3 directionToObject;
directionToObject = objectThatShouldBeOutOfSight.position - camera.transform.position;
if (Vector3.Angle(camera.transform.forward, directionToObject) > camera.fieldOfView)
{
ScaryBoo();
}
I just tested your answer, and it seems to work with different aspects and it is certainly better than what I was going to do. Thank you! The only gripe I have is that it registers the object being out of sight a bit further off the actual screen than the play screen, although that can give it a bit of a delay so this is very likely the option I'm gonna go with.
Yeah, it's because when the camera FOV is, let's say, 90, then the object should be at 90 degrees off the camera line of sight. Actually, I should have wrote camera.filedOfView / 2f
in the code. But it will eli$$anonymous$$ate the delay then, so you probably would better use camera.fieldOfView * 1.5f
to have some delay.
Answer by ralpholiver · Nov 30, 2019 at 06:17 AM
There is an event called OnBecameInvisible which probably solves your issue. However, this might trigger too early. Consider a perfectly oriented north player, aligned with the said interest object. Depending on the size of the target, by the time you rotate around 45 degrees heading east, it would already trigger, when a perfect "away" situation would be at 180 degrees. If this bothers you, you can combine the event with your second approach, customizing and determining the boundaries where your action will take place, and checking only when the object is not on screen.
I like this option, it's nice and simple. The only issue is once the camera goes a certain distance down, it registers the object as seen in most situations. This works very well with out much input, although I think there's a good option here: I'm gonna mix this answer and the one made by Ermiq for the most effective but also efficient way (As you stated at the bottom).
When it triggers that the object is invisible then it works fine (I'm just looking for it to trigger on things like light bulbs and mannequins so nothing big to bug it out).
When it triggers that the object is visible then it will do the check Ermiq offers (Changed a little bit as it's on the object itself) to deter$$anonymous$$e if it really is invisible just being dumb.
This should work, thanks guys!