• 3D
  • Detecting whether an object is in view or hovered over

I have quite a few ideas in mind with many questions for each, and figured I'd start with an essential question which I'm going to need for many things I'll be doing. I'd like to know how I can probe the visibility of an object, as well detect whether the player is hovering over certain objects. Overall I'm curious about 3 different detection types which I'd prefer doing individually:

  1. How do I know if an object is within the player's field of view? Can you verify if a mesh is intersecting the active camera's FOV? Ideally Godot can cheaply check whether any vertice of the model intersects the camera and thus part of the mesh is visible, if not an estimated bounding box would work just as nicely.
  2. How can I tell whether an object is fully hidden behind an opaque surface? Can a Godot script currently assert when a model is poking behind a solid surface, and when it's fully masked by another model from the camera's perspective?
  3. What is the easiest way to check whether the mouse cursor or crosshair (virtual dot in the center of the screen) is positioned over an object and the player is hovering over them? I imagine a ray trace would be the easiest way, but am wondering if such detection can also be done in the 2D screen space which may be a cheaper solution.

Note that I'm not necessarily looking for this as a means of optimizing performance, as I'm aware Godot does (or will) support occlusion culling natively and that shouldn't be coded by projects. This is mainly to allow certain mechanics to work properly, the most common being spawners: In many cases you wish to have an invisible object spawn a character or item, however you only want that to happen when the player isn't looking so they don't notice someone / something popping into existence in front of them... the spawner must activate either when it's outside the camera FOV or hidden by an opaque wall. This can also be used so characters know when the player is looking at them and other fun stuff. Hover detection is itself essential so you can highlight and click on objects to interact with them.

Also note that I aim to work primarily with visualscript. An answer for achieving those detections in gdscript will definitely help most developers, but if possible I'd like to know what vscript functions could be used as well. Existing demos in this regard would also be helpful if anyone has made any as of yet.

For question 1, make use of the VisibilityNotifier node (API reference).

Question 2, Godot currently does not have any built in feature that can check for occlusion, though you could try defining large area boxes (in places where objects spawn in) and declare it occluded if a ray fired from it towards the player does not actually hit the player.

Question 3, I think Godot can do screen rays (though I don't know for sure if there's functions for projecting a bounding box to 2D screen space).

@"Ace Dragon" said: Question 3, I think Godot can do screen rays ...

The documentation for ray-casting shows example code that lets you raycast from a Camera. I have use raycasting from a camera several times and it works pretty well!

According to the same article in the documentation, CollisionShape has a function for detecting mouse clicks. It seems you can use the input_event signal on a CollisionShape node to detect clicks (and other input events?) on a CollisonShape. I have not used it before, but it may be worth looking into!

Ray casting would actually solve #3, as you can check whether the camera and the object are in line of sight from one another. If it's a single ray of course, you do run into the issue that you're comparing the camera to the origin of the object... you'd still get a valid answer if only part of the object was poking through the wall. So you'd have to run a ray against each of the 8 corners of the bounding box to be sure.

And that's a very helpful answer, thank you: I didn't find any info about input_event for 3D objects, only 2D menu items. I thus assumed there was no detection for whether the mouse cursor is touching a model in 3D space, and I'd have to use a ray trace or other positional detection manually to achieve that.

You can convert a 3D point's coordinates to viewport coordinates using Camera.unproject_position() and do the opposite using Camera.project_position().

@Calinou said: You can convert a 3D point's coordinates to viewport coordinates using Camera.unproject_position() and do the opposite using Camera.project_position().

Sweet, thanks! Is there an easy way to convert a whole model's projection into a 2D polygon however, then easily determine if the cursor (or even another element on the HUD) is intersecting it? While the input_event call may work for mouse clicks, it may not detect hovering and do stuff like highlighting the object and showing a "left click to grab" message.