I have a some cameras that are build up like security cameras and they should detect if a object is visible on screen.
To do that I want to send out some raycasts whenever I open my camera to see if there is a gameobject with a specific tag.
And if there is an entirely different way to approach this (with not using raycasts) then please tell me how.
I can’t just use renderer.isVisible and void OnBecameVisible because they are both not working for some reason.
I also wasn’t able to find a good video online about this topic, because they all just show how to shoot a raycast in front of you in a straight line and this would not work if the gameobject is in the corner of the camera.
Maybe I’m missing something here, but I would really appreciate if you could tell me if its even possible to shoot raycasts and like this and if yes if you could recommend a good tutorial on how to do that.
shoot out a bunch of rays towards a grid of points in front of the camera. So first, create a grid of vector3 points, then cast a ray in the direction of each point.
You can use an actual camera, then use the frustum to check overlaps
Create a mesh in the shape of a cone in a 3D software (blender) then use it as a trigger collider to detect objects.
Create a procedural mesh then use that as trigger collider.
If you go to this asset (Sensor Toolkit), they have documented exactly the methods they have used.
Sebastian Lague has a tutorial about sensors too, So you can apply this method in a 3D space once you understand how it’s done.
The “viewport” is a description of screen space where (0,0) is the bottom left and (1,1) is the top right, while Z is the distance in front of the camera (so the .z > 0f part is checking to make sure it’s in front of the camera). So you convert the target object’s position to this space, and you can see if its center is within the screen.
You could do a Raycast in the direction of this point to make sure it’s not obscured by other objects:
Vector3 direction = targetTransform.position - Camera.main.transform.position;
if (Physics.Raycast(targetTransform.position, direction, out var raycastHit)) { // I forget actual racyast syntax/parameter order, check docs if this doesn't work
if (raycastHit.gameObject.transform != targetTransform) {
Thanks to both of you this was exactly what I needed.
I now have a basic working code. However I think how I did this is a really bad way of handling it, because its a lot of messy code and gameobjects. (TriggerEnter and TriggerExit with a lot of gameobjects and bools)
So I would like to use your code as a base, but I have a few questions.
In your first Script you have created a a view port. And you said that I can check if a target is on the camera.
How does this code work?
Do I have to place this code inside of my camera script and run it every time I change the camera?
And how can I check if the target is inside of this range like you said?
You say I’ve “created a view port”, which is not a correct way of thinking about it. “the viewport” isn’t an object, it’s just a mathematical idea, representing the on-screen viewing space of the camera where points within the screen are within (0,0) and (1,1). So converting the world position to viewport space just makes the position a more convenient Vector3 to work with for our purposes, because (0,0) and (1,1) in that particular mathematical space is actually meaningful for us in a way that whatever the world position is, is not meaningful.
This code as written doesn’t depend on being attached to any particular object. Camera.main is a Unity convenience feature that finds a Camera with the MainCamera tag (which the default-created Camera object in the sample scene has). If you want to use a camera besides that one, you’ll need to assign that Camera as a reference on a public variable and use that. (The same applies to the targetTransform object I used in that script)