Godot: Screen drag speed doesn't work on Android

Created on 7 Feb 2016  路  9Comments  路  Source: godotengine/godot

It seems that when you grab the input of a screen drag and get the event.speed to apply to linear velocity. It does not work on the device but works on the editor.
This is the code that i am using

func _input(event):
    if(event.type == InputEvent.SCREEN_DRAG):
        dir = event.speed
        set_linear_velocity(dir)
bug android input

Most helpful comment

CC @RandomShaper in case you're now familiar with this code.

All 9 comments

( 2.0.3stable, official templates )
event.speed seems to work on Windows, but after exporting to Android it's always (0,0)

( 2.1.4, official templates )
Tested on Fedora, just reporting this bug still exists on android exported games.

I made a workaround using another bug.
if (IsAndroid == false && event.speed.length() >= 150) || (IsAndroid == true && event.relative_pos.length() >= 6):

The bug is that relative_pos does something different on Android and PC as well. On PC is seems to be clamped between -1 and 1 (albeit it "glitches" and sometimes goes up to 2 or 4 iirc) but on Android it reports the exact number of pixels from the last input process (so it's a per-frame difference (or however often these input processes occur). It's trial and error but uh.. it's better than writing out a more "complex" position difference calculation.

(3.0-stable, official templates)
Same thing still happens, speed is 0 on Android.

This has been my workaround as of now. Would be nice if we could get speed from the event though.

func _input(ev):
    if (ev is InputEventScreenDrag):
        $Camera2D.translate(Vector2(0, -ev.relative.y))
    elif (ev is InputEventScreenTouch):
        isDragging = ev.pressed
        if ev.pressed:
            touchTime = OS.get_ticks_msec()
            touchPosition = ev.position.y
            dragSpeed = 0
        else: 
            var distance = touchPosition - ev.position.y
            var elapsedTime = (OS.get_ticks_msec() - touchTime) / 1000.0
            if distance != 0 and elapsedTime != 0:
                dragSpeed = -distance / elapsedTime

This is still valid in 3.0.2. The speed vector is always (0, 0) in Android.

Just ran into this. Still the case in 3.0.4.

My workaround (which is a very rough approximate but serves my purpose of ignoring inadvertent screen drags when just touching) looks like:

if event is InputEventScreenDrag:
        if event.speed == Vector2(): # we're on a device and speed is broken
            event.speed = event.relative

When I looked at the code it seems like on both iOS and Android speed isn't being set, only relative:
On iOS:
https://github.com/godotengine/godot/blob/085483e88577ea91400a1ee46bc4321340824c51/platform/iphone/os_iphone.cpp#L216

And Android:
https://github.com/godotengine/godot/blob/80d6882ccd5380e62009d857454c87ca78da98bb/platform/android/os_android.cpp#L394

So I figured it was being set elsewhere later on, but couldn't find anything doing that. Windows, OS X, and X11 are doing something in the mouse handling that looks like: mm->set_speed(input->get_last_mouse_speed());
Which leads to:
https://github.com/godotengine/godot/blob/18c28c159d12c9d3227c2199998b271f7c5e5998/main/input_default.cpp#L39

So i suspect that speed is a mouse-only property. Which should be in the docs or added to devices to make them consistent (if emulate_mouse_from_touch is on?). I would guess if we can add an InputDefault *input; to Android and call mm->set_speed(input->get_last_mouse_speed()); for all of them that might help?

This is still broken on android in version 3.0.6! It was working for me a few months ago so I wonder who went ahead and removed the relevant code. And why!!

CC @RandomShaper in case you're now familiar with this code.

Was this page helpful?
0 / 5 - 0 ratings