Buttons in my game work on pc but they don't work on my phone (Android)

I’m having a big freaking problem for days, it is driving me nuts… I am developing a 2D game(snakes and ladders)for Android using Godot, and I am experiencing an issue where some of my UI buttons do not respond to touch on certain Android devices.

Project Information

  • Version: Godot 4.6.3 stable (official)
  • Programming Language: GDScript
  • Target Platform: Android
  • Game Type: 2D
  • Orientation: Landscape
  • Designed Resolution: 1280×720

For the main UI buttons, I am using the standard Godot Button node.

The main buttons on my menu include:

  • SettingButton
  • ShopButton
  • RulesButton
  • CharacterButton
  • StartButton

I also use a TextureButton inside one of my popups.

The main scene structure is approximately:

mainmenu
├── Menu (Sprite2D)
├── SettingButton (Button)
├── ShopButton (Button)
├── RulesButton (Button)
├── Label
├── CharacterButton (Button)
├── StartButton (Button)
├── coinbutton
├── CoinLabel
├── FeatherLabel
├── Timer
└── NoFeatherPopup
    ├── DarkBG
    ├── NoFeatherCard2
    └── TextureButton

The Problem

The problem is that the buttons do not respond correctly to touch on some Android devices.

I am running the game on the phones through USB Debugging / Debug over USB from Godot.

These are the test results:

Device / Environment Result
Running the game inside Godot on my laptop :white_check_mark: Buttons work
One Android phone belonging to a team member :white_check_mark: Buttons work
My Android phone :cross_mark: Buttons do not work
Three other Android phones belonging to team members :cross_mark: Buttons do not work

We are a team of five people. In total, the problem occurs on 4 out of 5 phones. Only one Android phone is working correctly.

Therefore, the issue does not appear to be specific to a single phone.

Settings I Have Already Checked

I checked the Inspector settings of the buttons.

For the main buttons:

Mouse Filter = Stop
Behavior = Inherited

I also have the following option enabled in Project Settings:

Emulate Touch From Mouse

Despite these settings, the problem still occurs on several Android devices.

Possible Causes

I am not sure what is causing the issue. It may be related to:

*Different screen resolutions or aspect ratios

*UI scaling, Viewport, Stretch, or Content Scale settings

*The actual clickable area or position of the Button

*Another Node overlapping the buttons

*Android touch input behavior or device-specific differences

My Questions

What should I check to identify the cause of this issue?

Is there any specific Godot 4.6.3 setting related to Button, TextureButton, touch input, Viewport/Stretch, UI scaling, or clickable areas that I should check?

Also, is there a recommended way to debug this on an Android device and see the actual clickable area of a Button and which Node is receiving the touch input?

You can check which Control is consuming the event by clicking on it while the game is running and check the Misc tab in the Debugger dock. Check if Last Clicked Control field shows anything. If it does, set that control Control.mouse_filter to Ignore and repeat.

As you can see in the screenshot, under Debugger → Misc, it shows:

So according to the Debugger, the ShopButton itself is being clicked.

However, on Android, _input() does receive InputEventScreenTouch, but the ShopButton’s gui_input callback is not triggered, and the button does not respond.

On PC, the button works normally.

What should I check next?

( In the previous post , I mentioned that settingButton/ShopButton/RulesButton/characterButton/startButton/coinButton were of type Button , but as you can see in the screenshot they are TextureButton not Button , I got a summary of my problem from chatgpt and it wrote that part wrong so should I change their type ?

Show us the code for handling the event

extends Node2D

@onready var no_feather_popup = $NoFeatherPopup
@onready var no_feather_card = $NoFeatherPopup/NoFeatherCard2

func _ready() → void:
# SaveManager.load_data()
# SaveManager.reset_feathers()
# To reset the number of feathers

MusicPlayer.volume_db = 0
load_coins()
update_feather_ui()

$Timer.start()

func update_feather_ui() → void:
var feathers = SaveManager.get_feathers()

$FeatherLabel.text = str(feathers) + "/3"

var left = SaveManager.get_remaining_time()

if feathers >= SaveManager.MAX_FEATHERS:
	$TimerLabel.text = "The feathers are full"
else:
	var minutes = left / 60
	var seconds = left % 60

	$TimerLabel.text = "%02d:%02d" % [minutes, seconds]

func load_coins() → void:
$CoinLabel.text = str(SaveManager.get_coins())

func _on_setting_button_pressed() → void:
get_tree().change_scene_to_file(“res://setting.tscn”)

func _on_rules_pressed() → void:
get_tree().change_scene_to_file(“res://rules.tscn”)

func _on_shop_button_pressed() → void:
print(“SHOP PRESSED, trying to load shop/shop.tscn”)
get_tree().change_scene_to_file(“res://shop/shop.tscn”)

func _on_coinbutton_pressed() → void:
Global.open_coins_page = true
get_tree().change_scene_to_file(“res://shop/shop.tscn”)

func _on_character_button_pressed() → void:
get_tree().change_scene_to_file(“res://shop/shop.tscn”)

func _on_timer_timeout() → void:
update_feather_ui()

func _on_start_button_pressed() → void:
if SaveManager.get_feathers() <= 0:
show_popup(no_feather_popup, no_feather_card)
return

get_tree().change_scene_to_file("res://game/Game.tscn")

func show_popup(popup, card) → void:
popup.visible = true

var final_scale = card.scale
card.scale = final_scale * 0.7

var tween = create_tween()
tween.tween_property(card, "scale", final_scale, 0.2)

func _on_texture_button_pressed() → void:
no_feather_popup.visible = false

func _input(event) → void:
print(“INPUT:”, event)

func _on_shop_button_gui_input(event: InputEvent) → void:
print(“SHOP GUI INPUT:”, event)

I should mention that By "feather “I mean the hearts/lives that are required to enter the game.”

Format your code so it is easier to read using this:

image

So, at first glance my first check would be to convert the mainmenu node to a CanvasLayer: Canvas layers — Godot Engine (latest) documentation in English

This will ensure that your UI elements sit on top of the gameplay elements and capture events first.

Next, I would look at if you are looking for a particular event that you have in your Input Map (Project Settings) or if you’re trying to handle any kind of input.

What do your debug logs say?

Thanks. Unfortunately I forgot to format it , just copied and pasted.

I’m not using a specific Input Map action. I’m using a TextureButton and its pressed() signal is connected to _on_shop_button_pressed().

I also tested the input directly with:

func _input(event):

	print("INPUT:", event)

On Android, the debug output shows both InputEventMouseButton and InputEventScreenTouch when I touch the ShopButton. For example:

INPUT:InputEventMouseButton: button_index=1, mods=none, pressed=true, canceled=false, position=((405.375, 599.8334)), button_mask=1, double_click=false

INPUT:InputEventScreenTouch: index=0, pressed=true, canceled=false, position=((405.375, 599.8334)), double_tap=false


However, _on_shop_button_pressed() is never called, and even the connected gui_input callback does not print anything.

On PC, the button works normally.

The mainmenu node is currently a Node2D, not a CanvasLayer. Would converting it to a CanvasLayer` be appropriate in this case?

It’s worth a try yes

I really appreciate your solution. It actually fixed my problem, so thank you very much for your help.

Now I have another problem. When I run the game on an Android phone, all of my buttons and Labels in the menu are displayed, but their positions become messed up and no longer match their original positions in the Editor.

For example, on my Main Menu screen, I have a tablet/plaque-like background, and the UI elements are placed on top of it. Everything is positioned correctly in the Editor, but on the phone:

Some buttons move to the left or right side of the screen.

Some elements move upward or downward.

The Labels are also no longer in their original positions.

For example, the Labels showing the number of coins and feathers, which are supposed to be at the top of the plaque, move to a different part of the screen on Android and may even appear above the plaque.

The buttons themselves are also visually displaced from their original positions.

Also, some of the other game screens do not have a background image at all, like the one shown in the screenshot. This seems to make the layout issue even more noticeable, because the UI elements are no longer positioned where they are supposed to be relative to the screen.

The important point is that the buttons actually exist and are clickable. The problem is NOT that they don’t work on Android.

For example, when I touch different parts of the screen, the buttons respond, but the actual touch/input area does not match the button’s visible/original position.

For example, I got this debug output for the ShopButton:

VIEWPORT SIZE:(1280.0, 720.0)

SHOP POSITION:(59.27271, 521.0)

SHOP SIZE:(872.7273, 1011.111)

And after another test:

SHOP POSITION:(632.0, 521.0)

SHOP SIZE:(300.0, 1011.111)

I only changed the size of the ShopButton for testing purposes, but the button became visually much smaller, and this did not solve the main problem.

Also, input is being received correctly on the phone. For example, for the ShopButton I get:

SHOP GUI INPUT:InputEventScreenTouch

And then:

SHOP PRESSED, trying to load shop/shop.tscn

So the ShopButton is receiving the touch input correctly, and its pressed signal is also being triggered.

Also, in the Debugger under Misc, when I click/touch the ShopButton, I see:

Clicked control = /root/mainmenu/ShopButton

Clicked control type = TextureButton

My buttons are TextureButton nodes.

The project resolution is:

1280 × 720

So the main problem I currently have is:

On Android, the UI is displayed, but the positions of the buttons and Labels become incorrect compared to the original layout in the Editor, and the actual touch/input areas do not match the visible positions of the UI elements.

What should I check or change so that all of my buttons and Labels appear in exactly the same positions on the Android phone as they do in the Editor when the project resolution is 1280×720?

Did you convert mainmenu into a canvas layer? If so, that may be why since it is the whole viewport. Have mainmenu be a Control node child of a CanvasLayer and that should work.

Yah I did convert that .

And also I changed mainmenu to be a control node child of CanvasLayer.(I couldn’t directly create the CanvasLayer as a parent node, so I right-clicked on the mainmenu node and clicked add child node, then when the CanvasLayer was a child of the mainmenu, I right-clicked on it and clicked make scene root, and that’s how I was able to create the CanvasLayer as a parent node of the mainmenu. Is that okay?)

You can see the scene tree and the first line of the code’"extends Control "

But It’s actually worse now bc before changing the mainmenu to a Control type , I was able to see the mainmenu’s background but now I can’t see it and the background has been gone.

This is the mainmenu's background .

For the mainmenu scene, only the buttons were messed up and it had a background, but now the buttons are messed up and haven’t been fixed yet, and the background of the mainmenu scene is gone too.

Ah right yeah, I replied hastily while on my phone and didn’t explain further, sorry about that.

This just comes down to understanding how UI works in Godot and to be honest, it just takes time playing around and adjusting things.

Here you can see my structure:

Since mainmenu is a simple Control node now, whatever background you set won’t show. I don’t know how you were displaying it before but you can change it to a Control type like PanelContaineror whatever you need and set the Theme Overrides/Styles/Panel to a StyleBoxTexture to the background you want. (there are other ways of course, this is just one way)

As for the buttons not showing, are you adjusting their Z-level or setting Top Level to true?

I don’t see how changing a Node2D into a Control would do this tbh, unless you’re making adjustments dynamically at runtime

I figured out what the problem was. The issue was with the button positions. I set the button positions directly in the code instead of positioning them manually in the editor. After doing that, the buttons are now positioned correctly on Android devices. Thank you again for your help!