Area2D doesn't receive InputEventMouseButton

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

I’m working on an town-building project.

I’m using Area2D to create building scenes so it can detect left click when I want to place it somewhere on the map. And it works fine in its own scene.

But when I try to instance it from the GUI scene (press a button from build menu), the building doesn’t detect the mouse button event anymore.

Instancing script of the GUI scene:

func _on_house_pressed():
$build_menu.hide()
var house = house_scene.instance()
get_tree().get_root().add_child(house)
pass

Building’s scripts:

extends Area2D

const x_grid = [0, 32, 96, 160, 224, 288, 352, 416, 480, 544, 608, 672, 736, 800, 864, 928, 992, 1056, 1120, 1184, 1284, 1312, 1376, 1440, 1504, 1568, 1632, 1696, 1760, 1824, 1888, 1952, 2016, 2080, 2144, 2208, 2272, 2336, 2400, 2464, 2528, 2592, 2656, 2720, 2784, 2848, 2912, 2976, 3040, 3104, 3168, 3232]
const y_grid = [0, 32, 96, 160, 224, 288, 352, 416, 480, 544, 608, 672, 736, 800, 864, 928, 992, 1056, 1120, 1184, 1284, 1312, 1376, 1440, 1504, 1568, 1632, 1696, 1760, 1824, 1888, 1952, 2016]

var state
var mouse_pos

var building = preload("res://sprites/structure/house0.png")
var backlayer
var available
var backlayer_available = preload("res://sprites/structure/4slotavailable.png")
var backlayer_unavailable = preload("res://sprites/structure/4slotunavailable.png")
var backlayer_building = preload("res://sprites/structure/4slotbuilding.png")
var backlayer_dismantling = preload("res://sprites/structure/4slotdismantling.png")

func _ready():
	available = true
	state = "placing"
	backlayer = backlayer_available
	pass 

func _process(delta):
	$backlayer.texture = backlayer
	if state == "placing":
		placing()
	elif state == "building":
		building()
	elif state == "functioning":
		functioning()
	elif state == "not_funtioning":
		not_funtioning()
	elif state == "dismantling":
		dismantling()
	pass

func placing():
	mouse_pos = get_global_mouse_position()
	for i in range(50):
		if x_grid[i] < mouse_pos.x and x_grid[i+1] > mouse_pos.x:
			self.global_position.x = x_grid[i]
		else:
			continue
	
	for t in range(25):
		if y_grid[t] < mouse_pos.y and y_grid[t+1] > mouse_pos.y:
			self.global_position.y = y_grid[t]
		else:
			continue
	pass

func building():
	backlayer = backlayer_building
	$building.set_texture(null)
	pass

func functioning():
	pass

func not_funtioning():
	pass

func dismantling():
	pass

func _on_house_area_entered(area):
	if area.is_in_group("structures"):
		backlayer = backlayer_unavailable
		available = false
	pass

func _on_house_area_exited(area):
	if area.is_in_group("structures"):
		backlayer = backlayer_available
		available = true
	pass

func _on_house_input_event(viewport, event, shape_idx):
	if event is InputEventMouseButton and event.pressed:
		if event.button_index == BUTTON_LEFT:
			print("clicked")
		elif event.button_index == BUTTON_RIGHT:
			self.queue_free()
		else:
			pass
	pass

Thanks.

Are you sure your mouse event is not captured by an invisible control node in top of the game? To check that when running the game, take a look at the Debugger in the editor, there is a Misc tab showing you which control you are clicking

Zylann | 2019-08-14 12:19

It said that “Clicked Control” is “root/gameui” (the top one of the GUI scene).

congbinh75 | 2019-08-15 01:26

What is gameui? Is it just a Control? Are you listening for input on this one? If not, set its mouse mode to Ignore. By default, Control nodes block mouse input, so there is a chance it caused input events to never reach the game behind.

Zylann | 2019-08-15 18:17

Yeah, “gameui” is actually a Control node. I understood. Thank you very much !

congbinh75 | 2019-08-16 02:30