#How do I simulate a mouse hover and click on a control node without the mouse?

55 messages · Page 1 of 1 (latest)

vestal silo
#

I am trying to make a smash bros character select screen and I was wondering...
how do I simulate multiple cursors on the screen?

Godot only supports 1 mouse but I would like for button nodes to recognize when my custom cursor is over it or is clicking

vestal silo
#

@raw gulch continuing the discussion from the ui channel... I tried to do this in godot 4.0 and it's not simulating pressed and focus on the button node...```
extends AnimatedSprite2D

@export_range(0,3) var id := 0
@export var input_map : Array[MyInputMap]
func _process(delta):
if id >= 0 && id < input_map.size():

    var input_vector = input_map[id].action_vector  .get_strength()
    var input_a      = input_map[id].action_button_1.is_just_pressed()
    var input_b      = input_map[id].action_button_2.is_just_pressed()
    
    global_position += input_vector
    if input_a: left_click()
    if input_b: right_click()

func left_click():
var e = InputEventMouseButton.new()
e.button_index = MOUSE_BUTTON_LEFT
e.position = global_position
e.pressed = true
Input.parse_input_event(e)
e.pressed = false
Input.parse_input_event(e)
func middle_click():
var e = InputEventMouseButton.new()
e.button_index = MOUSE_BUTTON_MIDDLE
e.position = global_position
e.pressed = true
Input.parse_input_event(e)
e.pressed = false
Input.parse_input_event(e)
func right_click():
var e = InputEventMouseButton.new()
e.button_index = MOUSE_BUTTON_RIGHT
e.position = global_position
e.pressed = true
Input.parse_input_event(e)
e.pressed = false
Input.parse_input_event(e)

#

this is my testing scene

#

also changing it from a animated sprite to a texture rect doesn't change anything

undone rose
#

Do you really need to simulate events? Seems like it might be easier to just handle input normally

#

Just keep track of what button the mouse is over, and call the relevant function

vestal silo
#

yes I do. also this doesn't work either... func left_click(): var prev = get_global_mouse_position() Input.warp_mouse (global_position) Input.action_press("ui_mouse_left") Input.warp_mouse (prev) await get_tree().process_frame prev = get_global_mouse_position() Input.warp_mouse (global_position) Input.action_release("ui_mouse_left") Input.warp_mouse (prev) func right_click(): var prev = get_global_mouse_position() Input.warp_mouse (global_position) Input.action_press("ui_mouse_right") Input.warp_mouse (prev) await get_tree().process_frame prev = get_global_mouse_position() Input.warp_mouse (global_position) Input.action_release("ui_mouse_right") Input.warp_mouse (prev)

#

nothing works it seems to button node is hardcoded to only accept mouse events from the os

vestal silo
undone rose
#

I think what you're trying to do seems more like a hack

vestal silo
#

alot of game engines support simulating mouse presses or at least they expose the ability to simulate ui states

undone rose
#

Sure, and Godot does as well. I just don't think this is a use case for that, especially if you're trying to handle multiple players

#

There's only one mouse cursor

vestal silo
#

what your suggesting means I can't use control nodes and would have to reprogram the whole ui system from scratch

undone rose
#

You can still use control nodes

vestal silo
#

yes right now it doesn't even let me use the real mouse for simulation

#

thats what the 2nd block of code I posted tries to do

undone rose
#

I think you need to use screen positions, which may not be the same as global positions

vestal silo
#

how do I do that?

undone rose
#

You'll need to find the screen position

vestal silo
#

is there a function for that?

undone rose
#

Not really

vestal silo
#

how would I do it?

undone rose
#

Math

vestal silo
#

you sound like my step dad

#

whats for dinner? food!

undone rose
#

It really depends, I don't know enough about how you have this set up

#

Plus I still think it's not the right path forward

#

How are you going to differentiate the different cursors?

vestal silo
#

I have an id

#
@export_range(0,3) var id        := 0
@export            var input_map : Array[MyInputMap]
undone rose
#

But how will the button click handler know which one it was?

vestal silo
#

hmm good point

#

ya idk

undone rose
#

Which is why this is the wrong solution

vestal silo
#

how would you do it again?

undone rose
#

Well, one reason

vestal silo
#

let me scroll up

#

so the problem is I need multipule cursors per player

undone rose
#

However these cursors are moved, have them keep track of what they are focused on, so you can just activate that option when needed

vestal silo
#

I can't just use 1

#

how do I get the control under it?

#

don't I need to know the control under it to keep track?

#

this would be good for a video or godot engine tutorial

#

I searched and noone has tried to do this yet

#

which is weird since smash bros is so popular

undone rose
#

Well for something like a character select, you don't necessarily need a freely moving cursor, you can just move around a grid

vestal silo
#

it's also team and stage select as well as type of player

#

less of type of character

vestal silo
#

@undone rose so I think I know what the problem is

#
        var local_position := get_local_mouse_position()
        Input.warp_mouse(local_position)```
#

this is the process event doesn't match my ingame cursor location

#

you can't see the mouse cursor but it's right there in the red circle

#

is there a way to get the location of the mouse in the scene?