First off, I am new here, so please excuse any misunderstandings on how to post.
I am brand new to Godot, and followed the tutorial on the homepage to create ones first 2D game. Great!
I am working on a very simple point and click adventure game with a friend, and by googling, I found out how to click and move the Player.
However, when I click something in the environment, a building for instance, I want the click to be handled by the function for the building only, and not make the player move.
Right now, I have a CharacterBody2D with a script:
func _physics_process(delta)
...
if Input.is_action_just_pressed("left_click"):
click_position = get_global_mouse_position()
...
And the main scene with a signal in the script:
func _on_area_2d_input_event(viewport, event, shape_idx):
if Input.is_action_just_pressed("left_click"):
print("clicked")
You can move your click position logic from _physics_process to _unhandled_input, and let the function called on the building click stop propagating the mouse event.
Something like this:
func _unhandled_input(event):
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
# move the player
func _on_area_2d_input_event(viewport, event, shape_idx):
if Input.is_action_just_pressed("left_click"):
# do your stuff
get_viewport().set_input_as_handled()
@FencerDevLog unfortunately your approach will not work, because _unhandled_input happens before _on_area_2d_input_event (physics picking), so the introduced set_input_as_handled() has no effect on the former.
For the moment, one way to deal with the situation is the following approach:
In your building-nodes track via mouse_entered/exited signals if the mouse is currently over one of the buildings.
In the script of your character-node, verify that the mouse is not over one of the buildings, before moving the character.
I deal with such in my game a lot. I setup a custom signal. I look for the mouse click event and send all clicks to the same signal function. If there’s a click where I don’t want it. I “handle” it by looking for it and ignoring it. I had to do that with left_button_released or my left_button_click event would get called twice: once for down and once for released.
Rather than trying to deal with the click at the high level, I also found that dealing with it at the lowest level worked better. All the “to_global()” and “to_local()” didn’t do anything to rectify where the event.position was saying the click occurred vs where the sprite was saying the click occurred.
In your situation, I’d look for 2 clicks. The first click selects the player or the building.
The 2nd click is what to do w what you selected.
Right-click clears the selection and allows you to use your 1st click to select something else.
If the player is selected on the 1st click, clicking the building would be internally the same as “move player to building”.
If the building is selected on the 1st click, a different series of actions would be taken.
@Sauermann helped me with a similar issue (and made me aware of this post) so I just thought I’d share what they helped me come up with in the hopes it’s useful.