This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
0 votes

If it were me designing the engine, I would have made _unhandled_input() happen AFTER the camera casts a ray, but that's not how things operate in godot: https://docs.godotengine.org/en/3.1/tutorials/inputs/inputevent.html

For example, in an RTS you could have a click on a unit select it, but a click on the "ground" be used for dragging the map. I could track all unhandled clicks and all physics object clicks and only pan the camera if I didn't select a unit, but that seems hacky. I can put an area/shape attached to the camera. I use get_tree().set_input_as_handled()but objects in the foreground don't block the background from getting input, it seems.

Is there a preferred/better way to go about this?

in Engine by (12 points)

I don't know the answer to your question, but in your example, I would expect the camera to pan even if I started the drag event on a unit: Press and release without dragging (= Click): Select unit (if applicable) - Press, drag and release: Pan the camera without selecting any unit. For this to work, it would not be relevant for the background event handler whether the same event was received by any other object before: Just set the game state to "drag mode" once the mouse is dragged with a pressed button, and let units only react to the release event when not in drag mode.

1 Answer

0 votes

I don't know how you are doing your pciking, but you can easily raycast to the ground by casting a ray with a collision mask which only matches the ground (snippet from my project):

func _physics_process():

    var mpos = get_viewport().get_mouse_position()
    var ray_pos = _camera.project_ray_origin(mpos)
    var ray_dir = _camera.project_ray_normal(mpos)
    var space_state = get_world().direct_space_state
    var ground_only = # your mask here
    var hit = space_state.intersect_ray(ray_pos, ray_pos + ray_dir * 200.0, [], ground_only)
    if not hit.empty():
        # Do stuff with the result

Then you could cache the result if you want to use it elsewhere.

by (29,510 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.