Emulating a lmb hold click on controller for inventory system ?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Rensae

HI guys ! I’m actually tidying up my code since there’s not much to do until the demo’s ready (replacing everything in static type, finishing little things like this lmb event button…)

And I’ve hit a wall. No matter what I try, it’s impossible for me to make this lmb event works. It only freeze, and fails to do so.

Here’s the code used :

 var showed:bool = false

var click = InputEventMouseButton.new()
var mouse_pos:Vector2

func _ready() -> void:
	self.hide()

func _physics_process(delta) -> void:
	if showed == true and GameData.controller == true:
		mouse_pos -= (Vector2(Input.get_action_strength("joy_left") - Input.get_action_strength("joy_right"), Input.get_action_strength("joy_up") - Input.get_action_strength("joy_down"))) * 7
		Input.warp_mouse_position(mouse_pos)
		click.position = mouse_pos

func _input(_event) -> void:
	if Input.is_action_just_pressed("l1") and showed == true:
		SceneHandler._unpause()
		yield(get_tree().create_timer(0.05), "timeout")
		$"../Test/Player"._loading_inventory()
		showed = false
		self.hide()
	if GameData.controller == true:
		if Input.is_action_just_pressed("cross"):
			call_deferred("_hold_left_click")

func _hold_left_click() -> void:
	click.set_button_index(1)
	click.pressed = true
	Input.parse_input_event(click)
    #click.pressed = false
    #Input.parse_input_event(click)

Here’s the goal : I want my player to be able to move the mouse when the inventory is showed (which works using the “get_action_strength”) and then be able to drag and drop the textures of the inventory.

I’m using the inner function of control nodes to do that (get_drag_data(), can_drop_data(), drop_data()), which should work fine since it works by a lmb event button when using the mouse.

I tried, just in case, to see if the control node had detected the mouse coming from using the controller as a… mouse doing a print on the event “mouse_entered”, and yes, it does. Better safe than sorry.

Back to the problem : If I try to emulate my left_click using the “cross” button of the controller, here’s what the output says :

Failed method: Control:_hold_left_click target ID: 1619

TOTAL BYTES: 4194288

NULL count: 0

CALL : 174761

CALL _hold_left_click: 1

Can’t really understand this one, didn’t get it once before. I just understand that it fails to call the method asked by call_deferred().

How does it works ? Is it impossible to emulate a holded lmb to drag and drop the textures of my inventory ?

Am I dumb and unable to see what’s the problem even though it’s a simple one ?

I’m thankful for your help, it’s been 3 days and I can’t keep hitting that wall forever.

var click = InputEventMouseButton.new()

Not an answer but you definitely do not want the above in global space. Add it to your _hold_left_click() function

No need for the showed as Spatial and Canvas nodes have an is_visible() getter function when you use show()/hide()

Wakatta | 2022-06-26 04:27

Oh I didn’t know about that, thanks !

It didn’t solve the problem I’m facing sadly, but it seems to react a lot better in any case !

Rensae | 2022-06-26 15:03

:bust_in_silhouette: Reply From: Wakatta

Noticed a hiccup

Avoid using Input.is_action_just_pressed in the Input func . . . . not that you cant or shouldn’t, its just really easy to miss the timing of it when you do.

So you can either do

var mouse_pos : Vector2

func _ready() -> void:
    self.hide()

func _physics_process(delta) -> void:
    if visible:
        if Input.is_action_just_pressed("l1"):
            SceneHandler._unpause()
            yield(get_tree().create_timer(0.05), "timeout")
            $"../Test/Player"._loading_inventory()
            self.hide()       
        if GameData.controller == true:
            mouse_pos -= (Vector2(Input.get_action_strength("joy_left") - Input.get_action_strength("joy_right"), Input.get_action_strength("joy_up") - Input.get_action_strength("joy_down"))) * 7
            Input.warp_mouse_position(mouse_pos)
            
            if Input.is_action_just_pressed("cross"):
                call_deferred("_hold_left_click")        

func _hold_left_click() -> void:
    var click = InputEventMouseButton.new()
    click.set_button_index(1)
    click.pressed = true
    click.position = mouse_pos
    Input.parse_input_event(click)

Or this

var mouse_pos : Vector2

func _ready() -> void:
    self.hide()

func _physics_process(delta) -> void:
    if visible and GameData.controller == true:
        mouse_pos -= (Vector2(Input.get_action_strength("joy_left") - Input.get_action_strength("joy_right"), Input.get_action_strength("joy_up") - Input.get_action_strength("joy_down"))) * 7
        Input.warp_mouse_position(mouse_pos)

func _input(event) -> void:
    if event is InputEventJoypadButton:
        if event.get_button_index() == JOY_BUTTON_LEFT_SHOULDER and visible:
            SceneHandler._unpause()
            yield(get_tree().create_timer(0.05), "timeout")
            $"../Test/Player"._loading_inventory()
            self.hide()

        if GameData.controller == true:
            if event.get_button_index() == JOY_BUTTON_X:
                var click = InputEventMouseButton.new()
                click.set_button_index(MOUSE_BUTTON_LEFT)
                click.set_pressed(event.is_pressed())
                click.set_position(mouse_pos)
                Input.parse_input_event(click)

Oh I didn’t know about that, too. Guess there’s a lot I need to learn still…

I did it using the first one you showed me, since the second one didn’t seem to work (had to replace the "JOY_BUTTON_LEFT_SHOULDER" with only "JOY_L", or the x one with "JOY_SONY_X", but it didn’t seem to work…) WIll make some research on this one before switching to it since it seems way more optimized !

So, it seems like the click is made ! Hooray ! Its position seems also good ! One problem down !

But it still doesn’t grab the texture like it should do. It emulates a holded left click, right ? So in theory, the texture should come along the mouse when it’s moved. Instead it seems like it’s doing nothing (besides doing a click).

At least I don’t have a “Failed method” anymore ~

Does the control node innate function get_drop_data() differentiate an emulated click versus a manual click on a mouse ? Should I change something on those control nodes maybe ?

Once again, many thanks for your help !

Rensae | 2022-06-26 22:55