Input location of mouse/touch?

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

I am going to make an input system which depends on me being able to detect the location of a mouse or touch input on the screen. Basically, there will be a touch/click somewhere on the screen, and I will append the location of that touch or click into an array which will be used for gestures and on screen motions, so for example, 5 consecutive frames with increasing x value would be interpreted as a swipe to the right.

How might I go about this?

:bust_in_silhouette: Reply From: Wakatta

Create your own class that extends from inputs
Do all your input processing in _unhandled_input(event):
send input to rest of the engine for processing
Add as a Sigleton

Guestures.gd

class_name Guestures extends Node

class LongPress extends InputEventAction:
	const DELAY_TIME = 0.5
	var position = Vector2(0,0)
	var timer = Timer.new()

	func _init():
		timer.connect("timeout", self, "_on_long_press")

	func start(event):
		position = event.position
		if timer.is_stopped(): timer.start(DELAY_TIME)
		
	func is_valid():
		return position != Vector2(0,0)

	func cancel():
		position = Vector2(0,0)
		timer.stop()

	func as_text():
		return "GuestureLongPress : position=" + str(position)
		
	func _on_long_press():
		pressed = true
		Input.parse_input_event(self)

var touches = Array()
var drags = Array()
var long_press = LongPress.new()

func _unhandled_input(event):
	if event is InputEventScreenTouch:
		if event.pressed:
			touches[event.index] = event 
			if event.index == 0:
				long_press.start(event)
		else:
			touches.erase(event.index)
			drags.erase(event.index)
			if long_press.is_valid():
				long_press.pressed = false
				Input.parse_input_event(long_press)
			long_press.cancel()
		
	elif event is InputEventScreenDrag:
		drags[event.index] = event
		long_press.cancel()

Input.parse_input_event(event) sends the event to all nodes to be handled so you could do on any node

func _input(event):
    if event is Guesture.Longpress:
        if event.is_pressed():
            foo()

To add more Gestures just add more classes like for e.g

class Pinch extends InputEventAction:

another thing to note is if you want syntax highlighting for your gestures then add them to their own files and use class_name instead of class for e.g. class_name InputEventScreenLongpress extends InputEventAction

That helps, how might I make this also apply for mouse clicks?

psear | 2021-01-22 17:32

Set
Project Settings > Input Devices > Pointing > Emulate Touch from Mouse to true

or in the _unhandled_input(event):function change InputEventScreenTouch to InputEventMouseButton and InputEventScreenDrag to InputEventMouseMotion

Using both is also and option

Wakatta | 2021-01-22 20:25