I try to use "VisibleOnScreenNotifier3D" Node. But for example, if the object is placed behind the wall (MeshInstance3D), the "screen_exited" signal will not be called.
I would be grateful if you could suggest a way for me to check if the object is being rendered or not.
Thanks.
How to check if an object is visible in front of the camera?
xyz I am making a game where if the player sees the monster, the monster will stop moving.
I think you are wrong because I was working with Unreal Engine before I was working with Godot and I could do this using the WasRecentlyRendered function.
That is, if the monster was behind the wall but in the camera frame, it would still start moving until it is visible in front of the player's camera.
Maybe a raytrace from camera to the object, to see if itβs occulded? Then check the angles, to see if itβs outside the FoV?
- Edited
- Best Answerset by cynerboy
cynerboy I think you are wrong
That's highly unlikely But who knows, I well might be.
The engine cannot easily tell if an object is behind other object. Even if an objects is totally covered, it will still go through the rendering pipeline and it will be rasterized into pixels. Those pixels may or may not be drawn into final framebuffer, depending on what's in the depth buffer at the time of rasterization, but they will be processed nevertheless. This all happens in the graphics card on the pixel level and your script code has no easy way of concluding if an object is "behind" something.
In general there are 3 ways to completely skip pushing an object through the rendering pipeline. Their main purpose is performance optimization:
- explicit visibility toggle - this is self explanatory.
- frustum culling - object is checked against camera's viewing volume. It will be skipped if it's outside of it.
- occlusion culling - object is checked for occlusion by other objects in the scene which need to be specially assigned occluders. Those are typically some big, dominant elements in the scene.
The first two are straightforward and are routinely performed by most engines. The third one is tricky, can be computationally expensive and requires a special setup. Godot 4 can do occlusion culling but you'll need to set things up for every particular scene.
Godot can also notify you when object's visibility changes via VisibleOnScreenNotifier3D. It works for frustum culling but I'm not sure if it takes occlusion culling into consideration. You'll need to test it.
Afaik Unreal's WasRecentlyRendered()
only works for frustum culling as well.
As suggested by @axolotl, you could set up an approximative test using raycasts, which would probably be an optimal solution for your needs.
If you can target the left and right sides of its collider with two raycasts rather than just the center, that will probably give a better approximation of if it is fully "occluded". Idk if you can and where to easily get those extents from Godot other than just to calculate them yourself though.
- Edited
gd_qq A one raycast from the camera towards the desired object.
Your code style is:
step one: check the object in frustum culling
step two: if in frustum you can get point of location object then raycast to them (Note: Make sure your object has StaticBody or Area for colliding)
step three: check the collide name of object if true this mean you can see the object from your camera
It's easy.
Use a rays which is coming from monsters to a specific positions of a camera view. If a rays is not reach that camera view positions then the monster is not visible.