Skip to content

Instantly share code, notes, and snippets.

@Yagich
Created November 1, 2022 05:57
Show Gist options
  • Save Yagich/751ea2406f4d17d897b5ef83c953b91d to your computer and use it in GitHub Desktop.
Save Yagich/751ea2406f4d17d897b5ef83c953b91d to your computer and use it in GitHub Desktop.
a godot 4 function to get MeshInstances under the cursor
func pick(in: Node3D) -> Array:
var camera = get_viewport().get_camera_3d()
var center_pos = get_viewport().size / 2.0
var mouse_pos = get_viewport().get_mouse_position()
var from = camera.project_ray_origin(center_pos)
var to = from + camera.project_ray_normal(mouse_pos) * 50.0
var pick_results: Array[MeshInstance3D] = []
for m in in.get_children():
m = m as MeshInstance3D
var aabb = m.get_aabb()
# avoid using VisualInstance3D.get_transformed_aabb() as it will be
# removed in beta 4: https://github.com/godotengine/godot/pull/66940
# probably the most random removal i've seen, lol
# also note the order of operation is important:
# aabb * m.global_transform produces wrong results
# (seems to be inverted)
var global_aabb = m.global_transform * aabb
# it seems some click-through is still apparent,
# maybe using AABB.grow() is appropriate.
if global_aabb.intersects_ray(from, to):
pick_results.append(m)
if pick_results.is_empty():
return []
# sort by distance to the camera, in ascending order
pick_results.sort_custom(
func(a: MeshInstance3D, b: MeshInstance3D):
var cam_pos = camera.global_transform.origin
var adist = a.global_transform.origin.distance_squared_to(cam_pos)
var bdist = b.global_transform.origin.distance_squared_to(cam_pos)
return adist < bdist
)
# the actual occluded selection is pick_results[0]
return pick_results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment