How I can get the collider from the result of an intersect_ray in C++?

Godot Version

Godot 4.2.1

Question

How I can get the collider from the result of an intersect_ray in C++, on this I am clueless, I can’t even find on the source code how exactly the collider is returned on the Dictionary, a Ref, or a pointer? And how this code needs to be?

I have gotten the others “simpler” values working fine, like the result normal and position, that don’t involve reference, I guess.

I have already tried the workaround of getting the int collider_id, but I did not find a function like instance_from_id() on the godot-cpp module for gdextensions for getting the collider reference through that.

Some of my half done code:

...

Dictionary result = space->intersect_ray(params);

if (!result.is_empty()) {
    Vector3 result_normal = result.get("normal", Vector3(0, 0, 0));
    Vector3 result_point = result.get("position", Vector3(0, 0, 0));
    float result_length = params->get_from().distance_to(result_point);

    Ref<Node3D> result_collider = result["collider"];  <- how to get the thing idk?

...

The compiler important errors:

error C2039: 'reference': is not a member of 'godot::Node3D'
godot-cpp\gen\include\godot_cpp/classes/rigid_body3d.hpp(48): note: see declaration of 'godot::Node3D'
godot-cpp\include\godot_cpp/classes/ref.hpp(184): note: while compiling class template member function 'godot::Ref<godot::Node3D>::Ref(const godot::Variant &)'
scons: *** [.windows.template_debug.x86_64.obj] Error 2
scons: building terminated because of errors.
1 Like

I find a workaround for now, but feels it could be a better way:

It is using the Variant type for getting the collider value, the Variant type is kinda magic for me in this snippet, like an auto from the looks of it, but for Godot!

...

if (!result.is_empty()) {
	Vector3 result_normal = result.get("normal", Vector3(0, 0, 0));
	Vector3 result_point = result.get("position", Vector3(0, 0, 0));
	float result_length = params->get_from().distance_to(result_point);

	Variant result_collider = result["collider"];   <--- new stuff

...

It’s nice for exposing for GDScript. Then I use casting for checking and getting the pointer in C++, or use in GDScript, for example (this works fine, apparently):

C++:

Node3D* raycast_collider = cast_to<Node3D>(result_collider);

if (raycast_collider) {
	UtilityFuctions::print(raycast_collider->get_name());
}

GDScript (wiith the bindings):

if get_raycast_collider() is Node3D:
	print(get_raycast_collider().name)
1 Like

The function returns an empty dictionary if nothing collides. If it collides and the collider isn’t valid, result[“collider”] will be nullptr. If it collides and there is a collider, result[“collider”] will be a pointer to the object.

The two intersect ray functions are in physics_server_3d.cpp and godot_space_3d.cpp. The function _intersect_ray() in physics_server_3d.cpp returns the dictionary, but the computation is done in intersect_ray() in godot_space_3d.cpp.

Collider can be Object *result_collider = result["collider"];

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.