【Godot】Controlling Pause Functionality with Process Mode

Created: 2025-06-20Last updated: 2025-12-16

Learn Godot Engine's pause functionality and Node Process Mode. From basic usage to creating non-paused UIs, cutscene and dialogue applications, and performance considerations.

Overview

In game development, pause functionality is essential for letting players take a break or change settings. Godot provides get_tree().paused = true, a simple way to pause the entire game. However, you may encounter issues like "the UI can't be controlled after pausing" or "some characters keep moving."

The cause is often a lack of understanding of Process Mode. This article explains Godot's pause functionality basics, the Process Mode concept for mastering it, and advanced implementation techniques.

Process Mode Settings Screen

Basics of Pause Functionality in Godot

To stop most of the game loop in Godot, you manipulate the scene tree's paused property.

# Get scene tree and toggle pause state
func toggle_pause():
    get_tree().paused = !get_tree().paused

    if get_tree().paused:
        print("Game paused.")
    else:
        print("Game resumed.")

When you execute get_tree().paused = true, Godot stops the following:

  • _process(delta) and _physics_process(delta) calls
  • Physics calculations (collision, gravity, etc.)
  • InputEvent processing (with some exceptions)

However, this alone doesn't stop "all nodes." Process Mode is what individually controls which nodes are affected by pause.

Process Mode: Five Modes for Controlling Pause

Process Mode is a setting that determines how each node responds to the scene tree's pause state (get_tree().paused). You can set it from the Node > Process category in the inspector.

ModeBehaviorPrimary Use
InheritInherits the parent node's setting. This is the default.Most nodes in a scene. When no special control is needed.
PausableStops processing when get_tree().paused = true.Players, enemies, moving backgrounds—core gameplay elements.
WhenPausedProcesses only while get_tree().paused = true.Pause menus, settings screens, dialogues—UI you want interactive during pause.
AlwaysContinues processing regardless of get_tree().paused state.Singletons (autoloads), BGM management, online communication, etc.
DisabledNever performs any processing (_process, _physics_process, _input).Objects to temporarily disable, debugging nodes.

Important Point: Since Inherit is the default, changing a root node's Process Mode affects all its children.

Practical Use Cases and Code Examples

Use Case 1: Implementing a Robust Pause Menu

You need to stop the game while keeping the menu UI interactive.

Step 1: Create a Pause Management Singleton (PauseManager.gd)

# PauseManager.gd
extends Node

const PAUSE_MENU_SCENE = preload("res://ui/pause_menu.tscn")

var is_paused: bool = false
var pause_menu_instance: Control = null

func _unhandled_input(event: InputEvent) -> void:
    if event.is_action_pressed("pause"):
        is_paused = !is_paused
        get_tree().paused = is_paused

        if is_paused and pause_menu_instance == null:
            pause_menu_instance = PAUSE_MENU_SCENE.instantiate()
            get_tree().root.add_child(pause_menu_instance)
        elif not is_paused and pause_menu_instance != null:
            pause_menu_instance.queue_free()
            pause_menu_instance = null

Register this script as a singleton in "Project Settings > AutoLoad."

Step 2: Configure the Pause Menu Scene (pause_menu.tscn)

  1. Create a scene with a Control node as root.
  2. In the root node's inspector, change Node > Process > Mode to WhenPaused.
  3. Add Button nodes like "Resume Game" and "Return to Title" to this scene.

Use Case 2: Implementing Cutscenes

During cutscenes, you want to disable player control while continuing specific character and camera animations.

# CutsceneTrigger.gd (Attach to Area3D, etc.)

@export var animated_characters: Array[Node]
@export var animated_camera: Camera3D

func _on_body_entered(body: Node) -> void:
    if body.is_in_group("player"):
        start_cutscene()

func start_cutscene() -> void:
    get_tree().paused = true

    # Temporarily change Process Mode for nodes to animate during cutscene
    for character in animated_characters:
        character.process_mode = Node.PROCESS_MODE_ALWAYS
    if animated_camera:
        animated_camera.process_mode = Node.PROCESS_MODE_ALWAYS

    $AnimationPlayer.play("cutscene_animation")

func _on_animation_player_animation_finished(anim_name: StringName) -> void:
    if anim_name == "cutscene_animation":
        end_cutscene()

func end_cutscene() -> void:
    get_tree().paused = false

    # Restore Process Mode (Important!)
    for character in animated_characters:
        character.process_mode = Node.PROCESS_MODE_PAUSABLE
    if animated_camera:
        animated_camera.process_mode = Node.PROCESS_MODE_PAUSABLE

Common Mistakes and Best Practices

Common MistakeBest Practice
Calling get_tree().paused everywhereCentralize pause state management in a singleton (autoload) and avoid direct manipulation from other scripts.
UI freezes during pauseVerify that the Process Mode of UI root nodes you want interactive during pause is set to WhenPaused.
Overusing Always modeLimit Always mode to truly necessary nodes (BGM, singletons, etc.). Overuse degrades performance during pause.
AnimationPlayer doesn't stopIf AnimationPlayer doesn't sync with pause, check its Process Mode setting. Change to Pausable to make it stop with the game pause.

Performance and Alternative Patterns

Performance Considerations

  • Always is a last resort: Always mode can degrade performance during pause.
  • Smart savings with Disabled: For temporarily unnecessary nodes, setting Process Mode to Disabled reduces CPU load.

Alternative Pattern: Pause Management Without get_tree().paused

Since get_tree().paused affects the entire scene, for more localized control, you can have a singleton maintain its own pause state flag.

# Player.gd
extends CharacterBody3D

func _process(delta: float) -> void:
    if GameStateManager.is_gameplay_paused:
        return
    # ...normal processing...

Since Godot's standard get_tree().paused and Process Mode handle most cases, consider this alternative only for specific advanced requirements.

Summary

get_tree().paused and Process Mode are powerful Godot features. Understanding and properly using these two enables elegant implementation of various essential game situations: pause menus, cutscenes, dialogue displays, and more.

  • Pause Basics: get_tree().paused = true stops most of the game.
  • Key to Control: Process Mode allows fine-grained per-node behavior settings.
  • Best Practice: Centralize pause management in a singleton and set UI Process Mode to WhenPaused.
  • Performance: Avoid overusing Always mode and use Disabled mode wisely.