Block event after touching TouchScreenButton

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

I developed an small game for phones and after some tests with TouchScreenButtons I noticed that pressing them doesnt consumes the event: I get a raycast in my floor too. How can I prevent the touch event going beyond the button and being interpreted as a touch in my floor? Maybe I need to place some invisible UI element under the button?

:bust_in_silhouette: Reply From: code

Hi instead of _input(event) method, make use of unhandled_input(event) method

I moved the raycast code to _unhandled_input and no raycast is made.

rogerdv | 2021-03-03 17:37

Thx, works like a charm.

Favilla | 2022-04-10 14:11

:bust_in_silhouette: Reply From: Gerardo Gonzalez

I got the same issue with raycasting and a button event, to solve this issue for me I created a timer into raycasting process so you can press a button and call a method to avoid raycasting event. As a raycasting happens first, I exposed a method for calling later from my GUI in this case a button event. The timer is just a pause to wait if it can avoid the raycasting.

I did these steps:

  1. Raycasting happens from a camera.
  2. I created a timer in a camera script this for doing a pause (I used 0.2 seconds).
  3. A button event can release over your GUI and later this calls a method from your camera script to avoid a raycasting with a flag variable.

I solved this issue for my 3D game and it works now. Also I am searching a better way to solve this issue more elegant.

I found another solution and this is better than before one.

If you have a button on your screen you must use these two events.

  1. pressed()
  2. gui_input(event: InputEvent)

for your button of course.

func is_ui_event(event):
	if event is InputEventMouseMotion:
		return
	if event is InputEventScreenDrag:
		return
	if event is InputEventScreenTouch and event.is_pressed():
		get_tree().call_group("main_camera", "is_ui_event")
	if event is InputEventScreenTouch and not event.is_pressed():
		get_tree().call_group("main_camera", "is_not_ui_event")


func _on_btn_gui_input(event):
	is_ui_event(event)

My camera has this next code:

func _ready():
	add_to_group("main_camera")


func is_ui_event():
	ui_event = true


func is_not_ui_event():
	ui_event = false


func _input(event):
	if event is InputEventMouseMotion:
		return
	if event is InputEventScreenDrag:
		return
	if ui_event == false and event is InputEventScreenTouch and not event.is_pressed():
          # ALL YOUR CODE FOR RAYCASTING

If you have questions let me know.

Gerardo Gonzalez | 2021-05-02 21:22