Detect InputEventScreenDrag finish

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By agent3bood
:warning: Old Version Published before Godot 3 was released.

Hello
I have a scene like this
-Area2D
–CollisionShape2D
–Sprite

and the code to detect the drag event

func _input_event(viewport, event, shape_idx):
	if(event.type == InputEvent.SCREEN_DRAG):
		set_pos(event.pos)

but in the docs I could not find any signal to detect when the drag is over!

My game will be a simple drag a shape and drop it to a specific area, this is my first game so bear with me if this is so basic question.

:bust_in_silhouette: Reply From: volzhs

you can find it with InputEvent.SCREEN_TOUCH

if event.type == InputEvent.SCREEN_TOUCH:
    if event.is_pressed():
        pass # start touch which means start drag
    else:
        pass # stop touch which means stop drag

according to the docs

bool is_pressed ( ) Return if this input event is pressed. Not
relevant for SCREEN_DRAG events, always false.

agent3bood | 2017-12-18 13:59

@volzhs:
Oh cool move. Didn’t think of that. :slight_smile:

@agent3bood:
This is a SCREEN_TOUCH event used to determine if the area is touched (which is the requirement of every drag-event) - and so the is_pressed-method is valid.

rolfpancake | 2017-12-18 14:16

:bust_in_silhouette: Reply From: rolfpancake

I am not aware of such an event. This could be due to the fact that the InputEventScreenDrag is defined as a completed action. You directly get information about relative vector and speed and this is only possible if the drag-event is done.

In practise this leads to multiple drag-events when you only seem to drag once. I am not sure how these are determined by the engine but you can see yourself by just print a statement each time your area receives an InputEventScreenDrag.

As a workaround I’m using the method is_action_released in the input-event of the area. You only need to define a touch-InputEvent (same as leftmousebutton-click) and you can be sure that your drag is over when the click/touch is released.

I uploaded a sample project on zippyshare: dragger sample project

In the sample project there is one important thing: The released-method an the drag itself is registered in another Area2Ds input-event (the so called “drag-area”). This is due to the fact that a drag-event can not be detected beyond the borders of an area. So if your player has an Area2D which registered a touch-input the other area “is asked” if there was a drag-event. If so the player gets moved.

Here is the relevant code:

extends KinematicBody2D

# We could work with groups and then adding entities to a 'touched' group
onready var player_touched = false

func _on_area_input_event( viewport, event, shape_idx ):
	if event.is_action_pressed("ui_touch"):
		print("Touch on player pressed")
		player_touched = true

func _on_drag_area_input_event( viewport, event, shape_idx ):
	if event.is_action_released("ui_touch"):
		print("Touch on everything released")
		player_touched = false
	
	if player_touched:
		if event is InputEventScreenDrag:
			print("Player gets dragged")
			print("ply:", position)
			print("pos: ", event.position)
			print("rel: ", event.relative)
			print("vel: ", event.speed)
			
			### Moving the player ###
			# With collision
			#move_and_collide(event.relative)
			
			# Without collision
			position = position + event.relative

PS: I am using Godot 3 beta1 and I am not sure if this works in Godot 2 because the structure of the InputEvents has changed.

I did try is_action_pressed and it is not working

InputEventScreenDrag — Godot Engine (stable) documentation in English

Return whether the given action is being pressed. Not relevant for
SCREEN_DRAG events, always false.

agent3bood | 2017-12-18 15:30

Where there problems running the provided sample project?

rolfpancake | 2017-12-18 16:10

print(event.is_action_pressed("ui_touch"))

always false

agent3bood | 2017-12-18 16:28

Where did you place this line? Which Godot version?

rolfpancake | 2017-12-18 19:03

the line was placed in the _input(event)
version 2.1.4 linux

agent3bood | 2017-12-18 20:45

This could be due to the fact that my sample was build with Godot 3. But this should work in Godot 2 too.

Can you please upload the relevant part of your project (a minimum sample) so we can investigate further?

rolfpancake | 2017-12-18 20:57

rolfpancake, thank you for sharing!

DodoIta | 2017-12-22 17:19

:bust_in_silhouette: Reply From: angstyloop