Godot – Raycast from camera to world

Can anyone please tell me what is wrong with my code? I wrote this function in GDScript and then rewrote it in C#. It worked perfectly in GDScript but I seem to be getting an empty Dictionary in C#.

All I’m trying to do is cast a ray from the camera to the world.

GDScript:

func shootRay():
    var space_state = get_world().direct_space_state
    var mouse_position = get_viewport().get_mouse_position()
    rayOrigin = cam.project_ray_origin(mouse_position)
    rayEnd = rayOrigin + cam.project_ray_normal(mouse_position) * 2000
    var intersection = space_state.intersect_ray(rayOrigin, rayEnd)

    if not intersection.empty():
        return intersection

C#:

private Dictionary shootRay(){
    PhysicsDirectSpaceState spaceState = GetWorld().DirectSpaceState;
    Vector2 mouseScreenPos = GetViewport().GetMousePosition();
    _rayOrigin = _camera.ProjectRayOrigin(mouseScreenPos);
    _rayEnd = _rayOrigin + _camera.ProjectLocalRayNormal(mouseScreenPos) * 2000;
    Dictionary intersection = spaceState.IntersectRay(_rayOrigin, _rayEnd);

    return intersection;
}

Edit: It seems like when I hover only over a certain area of my viewport it does in fact detect a raycast, even if there is nothing in the world in that area. And even if I move the camera, the area it detects that object stays the same.

Edit: I had to change ProjectLocalRayNormal to ProjectRayNormal

>Solution :

It worked perfectly in GDScript but I seem to be getting an empty Dictionary in C#

You can see that GDScript specifically checks for an empty Dictionary:

    if not intersection.empty():
        return intersection

GDScript would return null in the case of an empty Dictionary (The method in GDScript does not specify a return type, so it returns a Variant, which is null if no return statement is hit). Which is not true for the code in C#.

You can read on the documentation of intersect_ray:

If the ray did not intersect anything, then an empty dictionary is returned instead.

Which confirms that an empty Dictionary is expected.


Addendum: Although I had not noticed at first, in the code in question translated project_ray_normal in GDScript to ProjectLocalRayNormal in C#. It should be ProjectRayNormal.

Leave a Reply