Could I access the input event that triggers a button's _pressed() function?

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

tl;dr
On touch screen devices, I want to access the index of the InputEvent that triggers a button’s _pressed() function, so that I can keep track of that input later without getting it confused with other touch inputs. Can I do this and if so, how?

What I’m trying to do:
I’m making a game for Android and iOS. For some buttons in the main scene, I want the player to be able to place their finger on them, and then drag the buttons around. The buttons then snap back to their original position when the player removes their finger from the screen.

How I’m currently trying to do it:

  • I have a TextureButton node for each draggable button, which is
    contained within a few different container nodes for proper positioning and scaling.
  • For each button, there is a corresponding Sprite node that has the same texture as the TextureButton. This is hidden by default.
  • When the TextureButton is pressed, it is hidden, and the Sprite is shown. The Sprite moves to the position of the TextureButton, making appear to be the same object.
  • The Sprite’s position while the player continues to have their finger on the screen is the position of the player’s touch.
  • When the player stops touching the screen, the Sprite is hidden and the TextureButton is shown.
  • The first stage of this process, where the TextureButton is hidden and the Sprite is shown, is done through the TextureButton’s _pressed() function. The rest I am planning to do in the scene’s _input(event) function.

What I’m not sure about:
In order to make sure that when the game does not behave oddly when there player has more than one finger touching the screen, I want to use the InputEvent’s index to make sure only the correct event is responded to. However, I’m not aware of any way to obtain this from a _pressed() function, where I’m assuming I would need to access it first. Is it possible to access it from within the _pressed() function or would I need to do it some other way (and if so, how)?

My code for this scene so far:

extends Node

export(NodePath) var sprayButton
export(NodePath) var sweepButton
export(NodePath) var sprayObj
export(NodePath) var sweepObj

# draggable buttons
onready var _sprayButton = get_node(sprayButton)
onready var _sweepButton = get_node(sweepButton)
onready var _sprayObj = get_node(sprayObj)
onready var _sweepObj = get_node(sweepObj)

# button dragging
var _pressedButton
var _draggedObj
var _touchID

func _ready():
	_sprayButton.connect("pressed", self, "drag", [_sprayButton, _sprayObj])
	_sweepButton.connect("pressed", self, "drag", [_sweepButton, _sweepObj])
	set_process_input(true)
	pass

func _input(event):
	
	pass

func _process(delta):
	
	pass

func drag(button, draggable):
	_pressedButton = button
	_draggedObj = draggable
	
	_pressedButton.visible = false
	_draggedObj.visible = true
	
	# this SHOULD get the draggable object to move to the position of the button it relates to, not sure if this will work though
	_draggedObj.position = _pressedButton.rect_global_position
	
	
	pass
:bust_in_silhouette: Reply From: volzhs

InputEventScreenTouch has index property that represents which finger.

var touched_index
func _input(event):
    if event is InputEventScreenTouch and event.pressed:
        touched_index = event.index
    if event is InputEventScreenDrag and event.index == touched_index:
        # you can drag from here
:bust_in_silhouette: Reply From: Maxpilot

Hi,

had a related scenario, and from my observation it is the case, that by touching a screen there are two events in parallel, a mouse event and a touch event. My guess is that the button “pressed” signal is derived from the mouse event, which has no touch id.

Solved this by using a Sprite with child Area2D with child CollisionShape2D, where “InputEventScreenTouch” and “InputEventScreenDrag” are captured in Area2D. If there is no overlapping of sprites, you have distinct assignment of touch events to a sprite. If sprites are overlapping, there has to be some management of Z-layer.