What am I doing wrong in this drag and drop script?

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

I have this piece of script for a drag and drop function. Now I want the drag and drop to stop when it leaves an area. But it doesn’t work. What am I doing wrong and does anyone know a possible solution?

Script:

var dragMouse = false

func _on_Area2D_input_event(_viewport, event, _shape_idx):
	if event is InputEventMouseButton:
		if event.is_pressed():
			dragMouse = true
			$DragAndDropTimer.start()
		else:
			dragMouse = false

func _on_DragAndDropTimer_timeout():
	$DragAndDropTimer.stop()
	dragMouse = false

func _on_DragAndDropMouseArea_area_exited(area):
	dragMouse = false

func _process(_delta):
	if linear_velocity >= Vector2(max_speed, 0): # Set truely max speed
		linear_velocity -= Vector2(10, 0)
	if (dragMouse):
		set_position(get_viewport().get_mouse_position())

This part should stop the drag and drop as soon as it is dragged out of the area.

func _on_DragAndDropMouseArea_area_exited(area):
dragMouse = false

Did you connect the signal?

Zoford | 2020-03-25 11:26

Yes I did…

rubendw03 | 2020-03-25 12:16

:bust_in_silhouette: Reply From: njamster

So as the script you provided is using linear_velocity I guess it’s attached to a RigidBody2D scene. In that case, it should look like this:

- RigidBody2D
  - Area2D
    - CollisionShape2D
  - Timer (named "DragAndDropTimer")

Connect the Timer’s timeout-signal to on_DragAndDropTimer_timeout() and the Area2D’s input_event-signal to _on_Area2D_input_event().

Now create another scene for testing, looking like this:

- Node2D
  - Area2D (named "DragAndDropMouseArea")
    - CollisionShape2D
  - An instance of your RigidBody2D

Now all that’s left to do i connecting the DragAndDropMouseArea’s area_exited-signal to the _on_DragAndDropMouseArea_area_exited in your RigidBody2D.

The script itself is perfectly fine and works for me. If it doesn’t for you, you probably will have to be a bit more specific about what exactly happens and where that differs from what you want to happen. However, with the information you provided so far, it seems you just made a mistake connecting your signals to their callbacks.

But the signal works fine, because when I insert ‘print(“out”)’ before the ‘dragMouse = false’ the function prints “out”. But the dragMouse part does nothing.

rubendw03 | 2020-03-25 13:19

So dragging the RigidBody2D around with the mouse works? Disabling the drag-and-drop-phase with the timer works also? But even though all signals are connected correctly, setting dragMouse = false on AreaExit does not work, whereas doing it on a Timer does? I cannot reproduce your issue, consider uploading an example project.

njamster | 2020-03-25 13:29

Yup everything works fine, except for the dragMouse = false par. I’ll upload the project.

rubendw03 | 2020-03-25 13:33

The issue is the same as with your last question: your connecting the area_exited-signal for one instance, namely the instance present in your Game-scene. However, this instance is invisible and distinct from other instances of that same scene your spawning later. So you have to connect the signal for each instance individually:

$Mouse/DragAndDropMouseArea.connect("area_exited", human, "_on_DragAndDropMouseArea_area_exited")

Like last time this goes into your _on_HumanTimer_timeout-function. Make sure you understand the difference between a scene and an instance of it!

njamster | 2020-03-25 13:58

Oh sorry! Thanks for the answer and time, again!

rubendw03 | 2020-03-25 14:16

Hey, I tried the things you suggested but the problem still remains. I really think it’s the “dragMouse = false” part that isn’t working, although I’m not sure…

rubendw03 | 2020-03-25 17:38