0 votes

Greetings!

I am going to keep it short: I have a menu which can be controlled by the left stick of a gamepad and via keyboard. Keyboard works fine, directional pad on controller too, but the left stick just creates bugs/straight up doesn't work.

Gif to show my problem:

http://imgur.com/a/Gehbu

Thanks in advance!

asked Aug 29, 2017 in Engine by Chain (69 points)

I need to test if is a bug but try to get only the initial "event" from _input_event and ignore the next ones until is released.

@eons Your suggestion works. If you just set a bool to ignore all is_action_pressed("ui_up") after the first one, until you get a is_action_released("ui_up"), this fixes the problem. Waaayy less code than the proposed answer (a couple extra lines to existing input code).

I would say this is a bug since is_action_pressed etc. should already have this built in for analogue inputs.

2 Answers

0 votes
Best answer

Thank you soooo much quijipixel!!! I would not have been able to do this without you!!

With your help I managed to create code which works and does the job exactly as I wanted. Here it is:

Variables:


const JOY_DEADZONE = 0.3
var axis1_x_value = 0
var axis1_y_value = 0

var pressed = false
var pressed2 = false

btns = [Array which contains all my Menu Buttons that I want to navigate through ]

Refreshing Axis:


func _fixed_process(delta):
axis1_x_value = Input.get_joy_axis(0, JOY_ANALOG_0_X)
axis1_y_value = Input.get_joy_axis(0, JOY_ANALOG_0_Y)

Listening to Input:


func _input(event):

# Down

btns[select_pos].grab_focus()

if btns[select_pos] == btns[btns.size() - 1] and axis1_y_value > JOY_DEADZONE and !pressed:
    select_pos = -1
    btns[select_pos].grab_focus()

if !pressed:
    if axis1_y_value > JOY_DEADZONE:
        select_pos += 1
        pressed = true
elif pressed:
    if not  axis1_y_value > JOY_DEADZONE:
        pressed = false

# Up

if btns[select_pos] == btns[-1] and axis1_y_value < -JOY_DEADZONE and !pressed2:
    select_pos = btns.size()-1
    btns[select_pos].grab_focus()

if !pressed2:
    if axis1_y_value < -JOY_DEADZONE:
        select_pos -= 1
        pressed2 = true
elif pressed2:
    if not axis1_y_value < -JOY_DEADZONE:
        pressed2 = false

It is not a very clean, effective or well thought out code. But it works.

Thank you :)

answered Aug 31, 2017 by Chain (69 points)
+1 vote

Game sticks are troublesome and there are several ways to get around them. I'll show you the way it worked for me:

const JOY_DEADZONE = 0.3

func _process(delta):
    var axis1_x_value = Input.get_joy_axis(0, JOY_ANALOG_0_X)
    var axis1_y_value = Input.get_joy_axis(0, JOY_ANALOG_0_Y)
    if axis1_y_value < -JOY_DEADZONE:
        up_pressed = true
    axis1_y_value > JOY_DEADZONE:
        down_pressed = true
    axis1_x_value > JOY_DEADZONE:
        right_pressed = true
    axis1_x_value < -JOY_DEADZONE:
        left_pressed = true

Every process call you have to poll the sticks current value. If you print the variables axis1_x_value and axis1_y_value you will notice that they range between -1 and 1. And that when the stick is released, it is probably not going back to 0. So using a constant (in this case JOY_DEADZONE) to check if it is pressed or not is a safer way to go.

answered Aug 29, 2017 by quijipixel (675 points)

Thank you for your reply. Your solution doesn't quite help tough. The Menu is as glitchy as it was before. JOY_DEADZONE with a value of 0.99925 is the closest thing to a usable menu.
Is my controller just so broken?

Wow, thats just too much. Have you tested it with other games? A value of 0.3 worked for me pretty well but 0.9 its just too much. You can try the Godots controller demo, there you can see how your controller is behaving.

I started Dishonored 2 a couple of times. Everything is behaving like it should. But in Godot it doesn't really work.

That might be a bug then. Place a post on github with the device, Godot version and computer specs.

it's not a bug!
You just have to make sure that you only move the focus once and then wait until the joystick has been released once.

var pressed = false

func _process(delta):
    if (!pressed && down_pressed):
        do_something()
        pressed = true
    elif (pressed && !down_pressed):
        pressed = false

Posted the final solution above. Thanks man :)

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.