0 votes

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.

asked Aug 14 in Engine by congbinh75 (48 points)

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

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

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.

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

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.