Input in Godot – Complete Guide

Understanding the Input Class in Godot 4 can unlock a new world of interactivity for your games. It’s the conduit through which players communicate their intentions to the game world, be it through pressing keys, clicking the mouse, or using a gamepad. Godot’s Input class provides a powerful and flexible system to manage these user interactions. Engaging with this system means tapping into an essential component of game development, creating responsive and intuitive gameplay experiences.

What is the Input Singleton in Godot 4?

The Input singleton in Godot 4 serves as a centralized node for processing various forms of user input. This system covers a broad spectrum of inputs, including:

  • Key presses
  • Mouse movements and button clicks
  • Gamepad buttons and joysticks
  • Touchscreen events

What is it Used For?

In practical terms, the Input class enables you to:

  • Map user actions to game controls
  • Check if a specific key or button has been pressed or released
  • Customize how input behaves, such as hiding the mouse cursor or capturing it within the game window
  • Integrate advanced input handling, such as gamepad vibration and processing custom input events

Why Should I Learn it?

Understanding the Input class is critical for game development as it directly relates to how players interact with your game. By learning this system, you can:

  • Ensure that your game is accessible and feels natural to play
  • Customize input handling to match the specific needs of your game
  • Create more complex and nuanced control schemes
  • Adapt your game to support multiple input devices, enhancing its reach and playability across different platforms

By mastering the Input class, you create the responsive link between player and game, essential for an engaging gaming experience. Let’s dive into the coding side of things and start bringing your game ideas to life!

CTA Small Image
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

Basic Input Events in Godot 4

To handle input in Godot, you’ll want to start with the most basic form of input detection. Let’s begin with key presses using the _input function. This function catches all input events that are not already handled by the _unhandled_input function.

func _input(event):
    if event is InputEventKey:
        if event.pressed and event.scancode == KEY_SPACE:
            print("Spacebar pressed!")

This code detects when the spacebar key is pressed.

Now, what if you want to constantly check if a key is pressed during a physics frame? Godot’s _physics_process function is perfect for that.

func _physics_process(delta):
    if Input.is_key_pressed(KEY_W):
        print("W key is being held down")

Next, let’s look at mouse input. The following example detects a left mouse button click:

func _input(event):
    if event is InputEventMouseButton:
        if event.pressed and event.button_index == BUTTON_LEFT:
            print("Left mouse button clicked!")

Handling Multiple Inputs

In many games, you’ll want to handle different inputs within the same function. Here’s how you can check for both keyboard and mouse input together:

func _input(event):
    if event is InputEventKey:
        if event.pressed:
            match event.scancode:
                KEY_A:
                    print("A key pressed")
                KEY_S:
                    print("S key pressed")
    elif event is InputEventMouseButton:
        if event.pressed:
            match event.button_index:
                BUTTON_LEFT:
                    print("Left mouse button clicked")
                BUTTON_RIGHT:
                    print("Right mouse button clicked")

Action Mapping and Input

Godot allows you to map keys and buttons to named actions, which can be later used in scripts for easier control management and reusability. First, you define the actions in the “Input Map” via the Project Settings, then you reference those actions in your code.

Checking if an action has been just pressed or released:

func _physics_process(delta):
    if Input.is_action_just_pressed("ui_accept"):
        print("Accept action just pressed!")
    elif Input.is_action_just_released("ui_cancel"):
        print("Cancel action just released!")

To exemplify continuous detection (holding down a button), let’s move a player sprite to the right:

func _physics_process(delta):
    if Input.is_action_pressed("move_right"):
        position.x += 10 * delta

Advanced Input Handling

Beyond basic presses, you sometimes need to capture and respond to more nuanced actions, like mouse motion or gamepad analog stick movement. Here’s how you capture mouse movement:

func _input(event):
    if event is InputEventMouseMotion:
        print("Mouse position:", event.position)

For gamepad stick movement, you can do this:

func _physics_process(delta):
    var joystick_vector = Vector2(
        Input.get_joy_axis(0, JOY_AXIS_0),
        Input.get_joy_axis(0, JOY_AXIS_1)
    )
    if joystick_vector.length() > 0.5:
        print("Gamepad left stick is being moved.")

These examples provide a solid foundation for handling input events in Godot 4. Coming up next, we’ll take a look at integrating these concepts into a more complete gameplay scenario. Stay tuned!Continuing from where we left off, let’s integrate more advanced input handling into common gameplay scenarios.

Controlling a Character

Suppose you have a player character that you want to move around the screen. Here’s how you can implement a simple control scheme for movement:

func _physics_process(delta):
    var movement_speed = 200
    var motion = Vector2()
    
    if Input.is_action_pressed('move_up'):
        motion.y -= 1
    if Input.is_action_pressed('move_down'):
        motion.y += 1
    if Input.is_action_pressed('move_left'):
        motion.x -= 1
    if Input.is_action_pressed('move_right'):
        motion.x += 1
    
    motion = motion.normalized() * movement_speed * delta
    position += motion

Shooting Projectiles

If the player can shoot, you’ll want to instantiate a projectile when a certain button is pressed:

func _physics_process(delta):
    if Input.is_action_just_pressed("shoot"):
        var projectile = Projectile.instance()
        projectile.position = position
        get_parent().add_child(projectile)

Interacting with Objects

For object interaction, such as opening a door or picking up an item, an action input can be used when the player is in proximity to the object:

func _unhandled_input(event):
    if event is InputEventKey:
        if event.pressed and event.scancode == KEY_E:
            if player_is_nearby_object:
                interact_with_nearby_object()

Implementing a Pause Menu

Pausing the game usually involves opening a pause menu:

func _input(event):
    if event.is_action_pressed("ui_pause"):
        get_tree().paused = true
        pause_menu.show()

Keep in mind that the `get_tree().paused` property will freeze the process and physics process of all nodes in the tree, except those with `pause_mode` set to ‘process’.

Customizing Mouse Cursor Behavior

Customizing the mouse cursor is often needed in gameplay. To hide the mouse cursor when the game starts or when a specific event occurs, such as entering a menu or beginning a level, you can use:

func _ready():
    Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)

Implementing Touch Screen Controls

Touch screen input is essential for mobile games. Handling a swipe motion, for instance, would look like this:

func _input(event):
    if event is InputEventScreenDrag:
        var swipe_vector = event.relative
        if swipe_vector.x > 100:
            print("Swiped Right")
        elif swipe_vector.x < -100:
            print("Swiped Left")

Handling Gamepad Vibration

Finally, for games utilizing gamepads, you may want to provide tactile feedback through vibration:

func _physics_process(delta):
    if Input.is_action_just_pressed("damage"):
        Input.start_joy_vibration(0, 0.5, 0.5, 0.5) # Start vibration
        yield(get_tree().create_timer(0.5), "timeout")
        Input.stop_joy_vibration(0) # Stop vibration after half a second

Exploring input handling further can greatly enhance the experience of your game. Remember to test on different devices and configure your input mappings to be as intuitive and responsive as possible for the player. Now go ahead and use these input techniques to make your game more interactive and fun!Incorporating different types of gameplay mechanics often involves unique input configurations. Here are more examples of how you can utilize the Input class in Godot to create engaging gameplay.

Double Jumping

A double jump is a common mechanic in platformers. Let’s see how it is implemented:

var can_double_jump = true

func _physics_process(delta):
    if is_on_floor():
        can_double_jump = true

    if Input.is_action_just_pressed("jump"):
        if is_on_floor():
            velocity.y = jump_force
        elif can_double_jump:
            velocity.y = jump_force
            can_double_jump = false

Charging Attacks

To charge an attack, you might want to track how long a button is held down. This example demonstrates a basic charging mechanism:

var charge_time = 0

func _physics_process(delta):
    if Input.is_action_pressed("charge_attack"):
        charge_time += delta
    elif Input.is_action_just_released("charge_attack"):
        if charge_time >= 1:
            print("Attack charged!")
        charge_time = 0

Adjusting Camera Zoom with Mouse Wheel

In games with zoomable views, you can adjust the camera’s zoom factor with the mouse wheel as shown below:

var zoom_level = 1

func _input(event):
    if event is InputEventMouseButton:
        if event.button_index == BUTTON_WHEEL_UP:
            zoom_level -= 0.1
        elif event.button_index == BUTTON_WHEEL_DOWN:
            zoom_level += 0.1
        zoom_level = clamp(zoom_level, 0.5, 2)
        $Camera2D.zoom = Vector2(zoom_level, zoom_level)

Using Touch Input for Movement in Mobile Games

For a virtual joystick on mobile games, you might process the screen touch input like this:

var touch_start_position = Vector2()
var touch_end_position = Vector2()

func _input(event):
    if event is InputEventScreenTouch and event.pressed:
        touch_start_position = event.position
    elif event is InputEventScreenDrag:
        touch_end_position = event.position

func _physics_process(delta):
    var direction = (touch_end_position - touch_start_position).normalized()
    if direction.length() > 0.1:
        position += direction * move_speed * delta

Press and Hold Game Mechanics

Some games require the player to press and hold a button for a duration to complete an action, such as charging a spell or lifting a heavy object:

var is_holding = false
var hold_time = 0
var required_hold_duration = 3

func _physics_process(delta):
    if Input.is_action_pressed("action_hold"):
        is_holding = true
        hold_time += delta
        if hold_time > required_hold_duration:
            complete_action()
    elif is_holding and Input.is_action_just_released("action_hold"):
        is_holding = false
        hold_time = 0

Complex Movement Patterns

For more advanced movement, you might want to combine several inputs to create complex patterns. In a stealth game, for instance, you could have a “sneak” mechanic:

func _physics_process(delta):
    var movement_speed = 200
    if Input.is_action_pressed("sneak"):
        movement_speed = 100 # Slower speed for sneaking
    motion = get_input_vector() * movement_speed * delta
    position += motion

func get_input_vector() -> Vector2:
    var input_vector = Vector2()
    input_vector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
    input_vector.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
    return input_vector.normalized()

There’s a vast array of gameplay interactions you can build using Godot’s Input class. Always remember to make your controls as intuitive as possible and to test thoroughly across all intended platforms and input methods. The more comfortable players are with your controls, the more they can focus on the fun and challenge of the gameplay!

Continuing Your Godot Journey

You’ve made a great start by delving into the Input class in Godot 4, unlocking the potential for rich player interactions. But this is just the beginning! To further your skills and expand your knowledge in Godot game development, why not explore our Godot Game Development Mini-Degree? It’s a curated collection of in-depth courses designed to take you from foundational concepts to advanced game development techniques in Godot 4.

Whether you are just starting out or looking to refine your existing skills, there’s always more to learn, and Zenva can help you every step of the way. For those who are eager to explore a broader selection of topics, we also offer a range of Godot courses suitable for all experience levels. Take the next step on your game development journey with us, learn at your own pace, and build the skills you need to bring your game ideas to life.

Conclusion

Embarking on your game creation journey with the power of the Input class in Godot 4 is just the beginning. As you continue to learn and experiment, you’ll find yourself crafting even more immersive and responsive gameplay experiences that captivate your players. Remember, each new skill you acquire brings you one step closer to realizing the full potential of your game designs.

Elevate your game development savviness with our Godot Game Development Mini-Degree, where every lesson is a building block for the next great game. Dive into a learning adventure with Zenva to unlock new possibilities and stand out in the world of indie game development. Your game development future is bright, and we’re here to light the way!

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.