Switching Input modes and handling player input for different game mechanics

Godot Version

v4.4.stable.official [4c311cbee]

Question

Hi all, I have been reading (and re-reading) Input because I am trying to implement a mini-game in my game similar to the terminal/strategem input in Helldivers 2.

Essentially, I want to process input once a player interacts with an object in game, and then handle all controller input for this mini-game. I am going to show icons on screen and have the user input controller actions. However, I don’t want the player to move, shoot, etc. While doing this. I want to temporarily have the player input focus over on the mini-game.

Okay, that is the summary. If you are interested in my thought process, here is my reasoning so far:

  • At first I thought, okay, perhaps I detect when a player has approached the terminal, show a control node, give it focus, and handle the inputs there. But I am using _input and on both the terminal and player nodes. Both were handled.
  • Then I thought, well, maybe I have a signal call to the player to change some kind of enum or bool, and I stop handling input in the player script altogether. But this would mean I need to handle state anytime I pause the game, create antother mini-game, etc. The structure of Godot input seems to act like a net, where things are handled and stop processing down the chain, so it felt like swimming against the design current. At least for as I understand it, I could be wrong.

This led me to believe I should just ask. I have read the docs and searched for examples but am left unsure about what direction to take. FWIW, this is the closest thing to what I am looking for: _gui_input vs _unhandled_input for key presses - #6

Thank you!

progress

If it helps, here is a .gif of what I want to accomplish along with the Control node code. How can I stop processing shooting on the player via the other node in the scene? Is setting a state on the player the ideal solution?

Terminal script

extends StaticBody3D
class_name HackingTerminal 

@onready var detection_component: DetectionComponent = $DetectionComponent
@onready var hacking_gui: Control = $Control

func _ready():
	detection_component.player_entered_detection_area.connect(_enable_hacking_mode)
	detection_component.player_exited_detection_area.connect(_disable_hacking_mode)

func _unhandled_input(event):
	if event.is_action("shoot"):
		print("Yep")
	
func _enable_hacking_mode():
	print("Hacking mode enabled")
	hacking_gui.set_focus_mode(Control.FOCUS_ALL)
	hacking_gui.grab_focus()
		
func _disable_hacking_mode():
	print("Hacking mode disabled")

partial Player movement script

func _physics_process(delta):
	handle_player_movement(delta)
	if Input.is_action_pressed("shoot"):
		shooting_component.handle_weapon_input()

Couple of solutions:

  1. Turn off physics processing for your player while in the mini-game.
  2. Turn off input processing for the nodes that are taking in input.
  3. Use only _unhandled_input() for your player, and use _input() for your minigame.

Going to give this a go in a handful of hours, thank you for the suggestions.

1 Like