Godot Version
4.4.1.stable
Question
I am designing a UI for a 3D game that has 3D elements in it (wanted something like the floating items in the Silent Hill 1 menu but a bit more diegetic):
However, I am currently having issues with tracking mouse events in my own 3D UI. I want to be able to check when a user is hovering their mouse over an item but my code that prints the "Hovering over: "… message never gets triggered. I have attached my script below.
extends SubViewport
var viewport_container: SubViewportContainer
@export var InventoryNode: SubViewportContainer
func _ready():
# Get the container reference
viewport_container = get_parent() as SubViewportContainer
if viewport_container == null:
push_error("Parent is not a SubViewportContainer")
return
# Enable mouse processing
viewport_container.mouse_filter = Control.MOUSE_FILTER_PASS
func _process(delta):
if InventoryNode != null and InventoryNode.is_visible():
# Only process when visible
check_hover()
func check_hover():
# Make sure required nodes exist
if viewport_container == null:
return
var camera = $Camera3D
if camera == null:
return
# Get mouse position relative to the viewport container
var mouse_pos = viewport_container.get_local_mouse_position()
# Check if mouse is within bounds of the viewport
if mouse_pos.x < 0 or mouse_pos.y < 0 or mouse_pos.x > viewport_container.size.x or mouse_pos.y > viewport_container.size.y:
return
# Convert mouse position to viewport coordinates
var viewport_mouse_pos = get_viewport().get_mouse_position()
# Raycast from camera
var from = camera.project_ray_origin(viewport_mouse_pos)
var to = from + camera.project_ray_normal(viewport_mouse_pos) * 1000
# Create physics query
var space_state = get_world_3d().direct_space_state
var query = PhysicsRayQueryParameters3D.create(from, to)
var result = space_state.intersect_ray(query)
if result:
print("Hovering over: ", result.collider.name)
# Handle hover event
if result.collider.has_method("on_hover"):
result.collider.on_hover()
My inventory item tree looks like this:
I am using "Own World 3D in the subviewport node:
I have also set the item(the tempgun) as a static body 3D with a CollisionShape3D (with layer 1 mask and layer in the collision setting).
What my inventory looks like when I in the “inspect inventory mode”: