Right-click input not working when UI is visible (Raycast + Enemy Selection)

Godot Version

4.4

Question

Also posted at r/godot (https://www.reddit.com/r/godot/comments/1lg1l8y/rightclick_input_not_working_when_ui_is_visible/)
Hello,
I’m currently prototyping a 3D top-down game in Godot and recently started adding a UI system. I ran into an issue when handling mouse input after displaying a UI panel.

I have a simple scene: a room with one player and two enemies.

First, here’s how the intended interaction system is designed:

Player Interaction System:

Player Actions:

mouse_left: used for movement and selecting enemies.

mouse_right: used to initiate attacks.

Left Click on the Map:

The player should move to the clicked location.

Left Click on an Enemy:

The enemy should be marked/selected.

A UI panel should appear showing:

Enemy’s name

Enemy’s level

Enemy’s current health

Left Click on Empty Space (while an enemy is marked):

The current enemy selection should be cleared.

The UI panel should be hidden.

Right Click on an Enemy:

The player should move toward the enemy.

Once within range, the battle should start.

The Problem:

After an enemy is marked (via mouse_left) and the UI panel appears, the player can still move by clicking on the map — which is correct.

However, mouse_right on another enemy does nothing.

It’s as if the mouse_right input is ignored or blocked when an enemy is already marked and the UI is visible.

If I unmark the current enemy (by mouse_left empty space, which hides the UI), then mouse_right works again as expected.

Relevant Code:

# player.gd
    @onready var navigationAgent: NavigationAgent3D = $NavigationAgent

    func _unhandled_input(event) -> void:
    	if can_move:
    		if event.is_action_pressed(mouse_left):
    			if target != null:
    				target = null
    
    			var result = dispathRay()
    			if result.has("collider"):
    				var col = result.collider
    				if col is Enemy:
    					if col == markedEnemy:
    						return
    					game_manager.unmark_enemy(markedEnemy)
    					markedEnemy = col
    					game_manager.mark_enemy(markedEnemy)
    					return
    				else:
    					if markedEnemy != null:
    						game_manager.unmark_enemy(markedEnemy)
    						markedEnemy = null
    
    			if result.has("position"):
    				var pos = result.position
    				navigationAgent.target_position = pos
    
    		if event.is_action_pressed(mouse_right):
    			var result = dispathRay()
    			if result.has("collider"):
    				var col = result.collider
    				if col is Enemy:
    					target = col
    					markedEnemy = target
    					game_manager.mark_enemy(target)
    		
    func dispathRay() -> Dictionary:
    	var camera: Camera3D = get_tree().get_first_node_in_group("Camera")
    	var mousePos: Vector2 = get_viewport().get_mouse_position()
    	var rayLength: int = 100
    	var from: Vector3 = camera.project_ray_origin(mousePos)
    	var to: Vector3 = from + camera.project_ray_normal(mousePos) * rayLength
    	var space: PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
    	var rayQuery: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
    
    	rayQuery.from = from
    	rayQuery.to = to
    	
    	return space.intersect_ray(rayQuery)

# game_manager.gd
    const MARK = preload("res://assets/common/mark.tscn")

    func mark_enemy(enemy: Enemy):
        PlayerHud.showEnemyCard(enemy)

        if enemy.get_node_or_null("Mark") != null:
            return

        var mark = MARK.instantiate()
        enemy.add_child(mark)

    func unmark_enemy(enemy: Enemy):
        if enemy == null:
            return

        PlayerHud.hideEnemyCard()

        var mark = enemy.get_node_or_null("Mark")
        if mark != null:
            mark.queue_free()

What I’m Looking For:

Why would mouse_right input stop working while the UI is visible, even with mouse_filter = IGNORE?

Is there a better way to structure this interaction logic to avoid UI interference?

Could this be related to how I’m managing selection or raycasting?

I’ve also tried to remove everything related to “mark”, to keep only with the show GUI part. But the problem persist.
Definitely something is consuming the input event. When the PlayerHud is active _unhandled_input isn’t called anymore.
None of my GUI nodes are set to full rect.

your ui ist already handling your click input?
Use the _input() function instead.

Ty for reply.
Even using _input the problem persists

For some reason, the PopupPanel was blocking mouse events.
I’m not sure why this was happening—if anyone knows and can explain it, I’d really appreciate it.
In any case, I replaced the PopupPanel with a regular Panel, and now everything is working as expected.