Manage a click release outside a CollisionShape2D

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By h1p3rcub3

Thanks in advance for the help.

The premise is simple. I’m trying to moving units from one building to another. To start the movement you have to start the drag in “Building X” and end it on “Building Y”.

The signals I want are:
"click" → When a building is clicked (can be click release)
"drag_start" → when the player clicks on the building and leaves the CollisionShape2D
"drag_end" → when the player succesfully ends the drag on a building
"drag_cancel" → when the player releases the mouse after a drag_start outside of a building

I have all the signals working but the "drag_cancel". I have a CollisionShape2D in each building to detect mouse events but i’m missing the click release because it happens outside the CollisionShape2D.

Every Building emits a signal to the main script. Here i show you the code that collects that signals and proccesses them.

var pressed = false
var dragging = false
var building_were_action_started = null
var building_were_action_ended = null

func on_building_mouse_press(building):
    pressed = true
    building_were_action_started = building

func on_building_mouse_release(building):
    building_were_action_ended = building
    if building_were_action_started == building_were_action_ended:
        print("ACTION -> Click")
    if pressed and dragging:
        print("ACTION -> End drag")
    pressed = false
    dragging = false

func on_building_drag_entered(building):
    pass


func on_building_drag_exited(building):
    if pressed:
        dragging  = true
        print("ACTION -> Drag start")

I tryed handling a input just for that, but it has it’s downs, as it will register when dropped correctly on a Building

func _unhandled_input(event):
    if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and !event.is_pressed():
        pressed = false
        if dragging :
            dragging = false
            building_were_action_started = null
            print("ACTION -> Cancel drag")

How can i manage a click release outside the shape? Is there a more optimal way to handle this? I’m i handling this in a absurd way?

Do you use Area2D nodes? I am pretty sure there is a mouse_entered() and a mouse_exited() signal under CollisionObject2D in the Node tab, when you select an Area2D node. Can you work with those signals? A signal is emitted every time the mouse exits a Building. Combine that with a check on whether the mouse has entered another Building and you got yourself a drag_cancel() signal.

johnygames | 2019-08-13 14:07

I use the mouse_exited() to start the drag. By combining the mouse_entered() and mouse_exited() I would only get the mouse release if the release was inside a building. I need to cancel the drag if the mouse is released outside of a building.

h1p3rcub3 | 2019-08-14 05:04

The mouse_exited() signal would alter a variable named exited. Then you would make a check to see whether the mouse is released (use Input.is_action_released() for that). If both the exited variable is true and the mouse is released, then emit the signal that you want.

johnygames | 2019-08-14 18:34