Assuming you have a RayCast3D node somewhere in your scene, you can do the following:
func _physics_process(delta : float) -> void:
if raycast.is_colliding():
var collider = raycast.get_collider()
var point = raycast.get_collision_point()
var normal = raycast.get_collision_normal()
Here, raycast
is a reference to a RayCast3D node (generated by @onready). You can then get all the good stuff like the collider, collision point etc.
Remember that all coordinates are in world space and thus global.
You can easily check whether you hit a pickup by checking collider.is_in_group("pickups")
.
Alternatively you can also create raycasts on-thy-fly. Dynamic raycasting is described in the offical docs.
And if you still want to use signals: Just extend the RayCast3D class and emit the signals yourself.
Happy coding!