I am trying to get the CollisionShape3D that is hit when a get_world_3d().direct_space_state.intersect_rayis made.
The dictionary returned contains the collider key, which comes back to the RigidBody3D parent of the collider shape. The shapekey contains presumably an index to the shape that was hit in the CollisionShape3D. How do I reference this shape to the CollisionShape3D?
This is the function I am using to query:
func _send_ray_from_screen_to_world(screenPoint: Vector2) -> Dictionary:
var from = camera.project_ray_origin(screenPoint)
var to = from + camera.project_ray_normal(screenPoint) * ray_length
var ray_query = PhysicsRayQueryParameters3D.create(from, to)
var collision = get_world_3d().direct_space_state.intersect_ray(ray_query)
return collision
The code I tried to use, which doesn’t populate collision_area:
var collision = _send_ray_from_screen_to_world(event.position)
var collided_rb : RigidBody3D = collision["collider"] as RigidBody3D
var shape_id = collision["shape"]
var shape_owner_id = collided_rb.shape_find_owner(shape_id)
var collision_area : Shape3D = null
if shape_owner_id != 0:
# shape owner found
collision_area = collided_rb.shape_owner_get_shape(shape_owner_id, shape_id) as Shape3D
I think I have managed to solve it. I think I got a bit confused.
The issue with the above code is that it tries to find Shape3D, not CollisionShape3D (which is what I want to get).
Additionally, there doesn’t seem to be a way to ask a Shape3D for its parent (probably as it is a Resource, not a Node).
The below code works to get the CollisionShape3D of a Shape3D from the Dictionary returned by get_world_3d().direct_space_state.intersect_ray:
var collision = _send_ray_from_screen_to_world(event.position)
var collided_rb : RigidBody3D = collision["collider"] as RigidBody3D
if collision["shape"] == 0:
return
var shape_owner_id = collided_rb.shape_find_owner(collision["shape"])
var collision_shape = collided_rb.shape_owner_get_owner(shape_owner_id) as CollisionShape3D
Though, I am not sure if there is an error path for CollisionShape3D.shape_owner_get_owner that I should be compensating for.
Looking at the C++ source code for CollisionObject3D - parent of CollisionShape3D (scene/3d/physics/collision_object_3d.cpp), it would only error if you passed in an invalid id, or if the shape does not have an owner (maybe if it has not been instanced as a part of a rigid body). I’ve added an if to be safe.