Приостановка игр и режима процесса

Введение

В большинстве игр желательно в какой-то момент прервать игру, чтобы заняться чем-то другим, например, сделать перерыв или изменить настройки. Реализация детального управления тем, что можно поставить на паузу (а что нельзя), — это сложная задача, поэтому в Godot предусмотрена простая структура для паузы.

Как работает пауза

Чтобы приостановить игру, необходимо установить состояние паузы. Это делается путём присвоения значения true свойству SceneTree.paused:

get_tree().paused = true

Это приведёт к двум последствиям. Во-первых, 2D- и 3D-физика будет остановлена для всех узлов. Во-вторых, поведение определённых узлов будет остановлено или возобновлено в зависимости от их режима обработки.

Примечание

Физические серверы можно сделать активными, когда игра приостановлена, с помощью их методов set_active.

Режимы процесса

У каждого узла в Godot есть "Process Mode", который определяет, когда он обрабатывается. Его можно найти и изменить в свойствах узла Node в инспекторе.

../../_images/pausemode.webp

Вы также можете изменить свойство с помощью кода:

func _ready():
    process_mode = Node.PROCESS_MODE_PAUSABLE

Вот что каждый режим предписывает узлу делать:

  • Inherit: Процесс в зависимости от состояния родителя, бабушки или дедушки и т. д. Первый родитель, который имеет состояние, отличное от "Inherit (Наследовать)".

  • С возможностью паузы: обрабатывать узел (и его дочерние элементы в режиме наследования) только тогда, когда игра не приостановлена.

  • WhenPaused: обрабатывать узел (и его дочерние элементы в режиме наследования) только тогда, когда игра приостановлена.

  • Всегда: Обрабатывать узел (и его дочерние узлы в режиме наследования) в любом случае. Независимо от паузы, этот узел будет обрабатываться.

  • Отключено: Узел (и его дочерние элементы в режиме наследования) не будут обрабатываться вообще.

По умолчанию все узлы имеют это свойство в состоянии "Inherit". Если родительский узел имеет значение "Inherit", то будет проверен прародительский узел и так далее. Если состояние не найдено ни в одном из прародителей, используется состояние паузы в SceneTree. Это означает, что по умолчанию при паузе игры все узлы будут приостановлены. Когда узел прекращает обработку, происходит несколько событий.

Функции _process, _physics_process, _input и _input_event вызываться не будут. Однако сигналы продолжают работать и вызывают запуск связанной с ними функции, даже если скрипт этой функции прикреплён к узлу, который в данный момент не обрабатывается.

Узлы анимации приостановят текущую анимацию, узлы звука приостановят текущий аудиопоток, а частицы также приостановятся. Они автоматически возобновятся после снятия игры с паузы.

Важно отметить, что даже если узел обрабатывает данные во время паузы игры, физика по умолчанию НЕ будет работать. Как уже упоминалось, это связано с тем, что физические серверы отключены. Физические серверы можно активировать во время паузы игры с помощью их методов set_active.

Пример меню паузы

Начнём созданием кнопки для установки игры на паузу.

Создайте меню с кнопкой закрытия, установите для Process Mode корневого узла меню значение When Paused, затем скройте меню. Поскольку для корневого узла задан режим обработки When Paused, все его дочерние и внучатые элементы унаследуют этот режим. Таким образом, все узлы в меню начнут обработку при постановке игры на паузу.

Прикрепите скрипт к корневому узлу меню, подключите созданную ранее кнопку паузы к новому методу в скрипте, а внутри этого метода приостановите игру и отобразите меню паузы.

func _on_pause_button_pressed():
    get_tree().paused = true
    show()

Наконец, подключите кнопку закрытия меню к новому методу в скрипте. Внутри этого метода снимите игру с паузы и скройте меню паузы.

func _on_close_button_pressed():
    hide()
    get_tree().paused = false

Теперь у вас должно быть работающее меню паузы.