+2 votes

I need to programatically "click" on items using the joystick. I've attempted a few methods to cause a left mouse click on whatever the mouse cursor is hovering over but I have had no luck. Here is what I've tried so far:

if event.is_action_pressed("ui_accept"):
    Input.action_press("mouse_click")

And

if event.is_action_pressed("ui_accept"):
    event.set_as_action("mouse_click", true)

"mouse_click" is simply set to the left mouse button in the Input Mappings. So it most likely isn't actually triggering a true click event. My game has lots of control widgets and I can't think of an easy way outside of causing a mouse down signal to know what the the user intends to click on.

in Engine by (57 points)

3 Answers

+4 votes
Best answer

You could add other inputs for the mouse_click action, e.g. you should be able to assign a joystick button to act as mouse click. This way you wouldn't have to handle faking mouse clicks yourself, as both a physical mouse click and a joystick input would be considered as the same actions.

If you do need to send a physical mouse click event from GDScript though, you can do that too. You need to craft an event, and send it. Something like:

var event = InputEvent()
event.type = InputEvent.MOUSE_BUTTON
event.button_index = BUTTON_LEFT
event.pos = selected_button.get_pos() # add here the proper position
get_tree().input_event(event)

(see the docs about InputEvent, InputEventMouseButton and @Global Scope

Alternatively you could also create an InputEventAction, see e.g. the InputEvent tutorial.

by (1,945 points)
selected by

This is exactly what I was looking for. I didn't now how to pass the created InputEvent back into the stack to be processed. I have a screen of sliders and buttons. Using gettree().inputevent(event) still didn't seem to cause the click on the controls. But I feel I'm on the right track.

In my above code snippet, I had forgotten to define the position of the mouse click event, I've fixed that.

You might also need to set event.pressed = true, I'm not sure. Check the class reference and experiment :)

Got to work! You need to send event.pressed = true followed by a false to simulate a "click"

    var evt = InputEvent()
    evt.type = InputEvent.MOUSE_BUTTON
    evt.button_index = BUTTON_LEFT
    evt.pos = self.get_global_mouse_pos()
    evt.pressed = true
    get_tree().input_event(evt)
    evt.pressed = false
    get_tree().input_event(evt)

This helped me out a lot! Exactly what I was looking for! Thank you!

For anyone coming across this using Godot 3.2, I found a few minor modifications were needed. The following function worked for me:

func click_the_left_mouse_button():
    var evt = InputEventMouseButton.new()
    evt.button_index = BUTTON_LEFT
    evt.position = get_viewport().get_mouse_position()
    evt.pressed = true
    get_tree().input_event(evt)
    evt.pressed = false
    get_tree().input_event(evt) 
0 votes

If your item is a button, you can try emit a pressed signal. Something like this:

my_button.emit_signal("pressed")
by (130 points)
It could be any control or object on the screen the user could click on with a mouse.

This doesn't work. It only simulates that button emitting the pressed signal. It doesn't actually press the button.

This matters in the case of a toggle button. It won't toggle.

0 votes

I prefer to do it like this:

if Input.is_action_pressed("mouse_click"):
pass #whatever you want to do here
by (216 points)

Note: You can still drag while holding down and it will trigger :P Might return unexpected results, haha.

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 Frequently asked questions and 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.