+1 vote

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!
http://docs.godotengine.org/en/stable/classes/class_inputeventscreendrag.html

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.

in Engine by (25 points)

2 Answers

+2 votes

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
by (9,674 points)

according to the docs

bool ispressed ( ) Return if this input event is pressed. Not
relevant for SCREEN
DRAG events, always false.

@volzhs:
Oh cool move. Didn't think of that. :)

@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.

+1 vote

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.

by (1,022 points)
edited by

I did try isactionpressed and it is not working

http://docs.godotengine.org/en/stable/classes/class_inputeventscreendrag.html#class-inputeventscreendrag-is-action-pressed

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

Where there problems running the provided sample project?

print(event.is_action_pressed("ui_touch"))

always false

Where did you place this line? Which Godot version?

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

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, thank you for sharing!

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 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 webmaster@godotengine.org with your username.