This is the testing Godot forums! All forum posts unique to this forum will be deleted! Please use the main forums here for any posts you want to keep. All forum rules still apply.

Detecting whether an object is in view or hovered over

MirceaKitsuneMirceaKitsune Posts: 43Member

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.


Tags :

Best Answers

  • Ace_DragonAce_Dragon Posts: 323
    Accepted Answer

    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).

  • TwistedTwiglegTwistedTwigleg Posts: 2,561
    Accepted Answer

    @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!

  • CalinouCalinou Posts: 376
    edited July 2018 Accepted Answer

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

Answers

  • Ace_DragonAce_Dragon Posts: 323Member
    Accepted Answer

    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).

  • TwistedTwiglegTwistedTwigleg Posts: 2,561Admin
    Accepted Answer

    @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!

  • MirceaKitsuneMirceaKitsune Posts: 43Member

    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.

  • CalinouCalinou Posts: 376Admin Godot Developer
    edited July 2018 Accepted Answer

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

  • MirceaKitsuneMirceaKitsune Posts: 43Member
    edited July 2018

    @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.

Leave a Comment

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.