How to make _input_event response first and stop the _unhandled_input with the same key input in different sub-scenes

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

I have a problem in Godot with input handle, in my game, the main scene contains two sub-scene, one is player, the other is box, however they use the same input like left mouse button click to trigger some different actions, in player.gd:

func _unhandled_input(event):
    if event is InputEventMouseButton && event.button_index == BUTTON_LEFT && event.pressed:
        # shoot...

in box.gd:

func _input_event(viewport, event, shape_idx):
    if event is InputEventMouseButton && event.button_index == BUTTON_LEFT && event.pressed:
        # drag or drop the box

As result, running the game, when I start dragging the box, the player will shoot at the same time, that’s not what I want, I want to realize that when dragging the box, the player stops shooting at once, and of course I know there’s one solution: dispatch the different input keys like BUTTON_RIGHT or Z/X/C for the player or box. But in this game it will feel no such intuitive then, so, is there another solution for the input? Tell me and thanks very much!

:bust_in_silhouette: Reply From: Eric Ellingson

You could make the box only draggable when a flag has been set via the mouse_entered event, then set that flag to false using mouse_exited. Likewise, when you react to the mouse_entered event, you could emit a signal to the player, setting a similar but opposite flag, i.e., when the box is draggable, the player can’t shoot, and when the box is not draggable, the player can shoot.

Alternatively, instead of signals, you could create an autoloaded script, and store that state there, which would be accessible from both the player and box scripts.

player.gd

var can_shoot = false

func _ready():
    connect_box_signals()

func connect_box_signals():
    for box in get_tree().get_nodes_in_group("draggable_box"):
        box.connect("toggle_player_shooting", self, "toggle_shooting")

func disable_shooting(enabled : bool):
    can_shoot = enabled

func _unhandled_input(event):
    if can_shoot && event is InputEventMouseButton && event.button_index == BUTTON_LEFT && event.pressed:
        # shoot...

box.gd

signal toggle_player_shooting
var is_draggable = false

func _on_BoxArea_mouse_entered():
	is_draggable = true
	emit_signal("toggle_player_shooting", false)

func _on_BoxArea_mouse_exited():
	is_draggable = false
	emit_signal("toggle_player_shooting", true)

func _input_event(viewport, event, shape_idx):
    if is_draggable && event is InputEventMouseButton && event.button_index == BUTTON_LEFT && event.pressed:
        # drag or drop the box

Thanks very much, and this works for me! Great!

SpkingR | 2019-07-29 06:28