Использование физической интерполяции
Как внедрить интерполяцию физики в игру Godot? Есть ли какие-то нюансы?
Мы постарались сделать систему максимально простой в использовании, и многие существующие игры будут работать с небольшими изменениями. Тем не менее, существуют ситуации, требующие особого подхода, и они будут описаны ниже.
Включение настройки интерполяции физики
Первый шаг — включить интерполяцию физики в Project Settings > Physics > Common > Physics Interpolation. Теперь вы можете запустить свою игру.
Скорее всего, ничего кардинально не изменится, особенно если вы используете физику со скоростью 60 транзакций в секунду или кратной ей. Однако за кулисами происходит гораздо больше.
Совет
Чтобы преобразовать существующую игру для использования интерполяции, настоятельно рекомендуется временно установить Project Settings > Physics > Common > Physics Tick per Second на низкое значение, например 10, что сделает проблемы интерполяции более очевидными.
Переместить (почти) всю игровую логику из _process в _physics_process
Самое фундаментальное требование к интерполяции физики (которую вы, возможно, уже выполняете) заключается в том, что перемещение и выполнение игровой логики над объектами должно осуществляться в рамках _physics_process (который выполняется на каждом такте физики), а не _process (который выполняется в отрендеренном кадре). Это означает, что ваши скрипты, как правило, должны выполнять основную часть обработки в рамках _physics_process, включая реакцию на ввод и ИИ.
Настройка преобразования объектов только в пределах физических тиков позволяет автоматической интерполяции обрабатывать преобразования между физическими тиками и гарантирует, что игра будет работать одинаково на любой машине. Кроме того, это снижает нагрузку на процессор при рендеринге игры с высоким FPS, поскольку логика ИИ (например) больше не будет выполняться в каждом отрисовываемом кадре.
Примечание
Если вы попытаетесь задать преобразование интерполированных объектов вне физического тика, расчёты интерполированной позиции будут неверными, и возникнет дрожание. Это дрожание может быть не заметно на вашем компьютере, но будет наблюдаться у некоторых игроков. По этой причине следует избегать задания преобразования интерполированных объектов вне физического тика. Godot попытается выдать предупреждения в редакторе при обнаружении такого случая.
Совет
Это лишь мягкое правило. В некоторых случаях может потребоваться телепортация объектов за пределы физического тика (например, при начале уровня или возрождении объектов). Тем не менее, в целом, трансформации следует применять из физического тика.
Убедитесь, что все косвенные движения происходят во время физических тиков
Учтите, что в Godot узлы можно перемещать не только напрямую в ваших скриптах, но и автоматически, например, с помощью твининга (tweening), анимации и навигации. Все эти методы также должны быть настроены на срабатывание по такту физики, а не по кадрам ("в режиме ожидания"), если вы используете их для перемещения объектов (эти методы также можно использовать для управления свойствами, которые не интерполируются).
Примечание
Также учтите, что узлы можно перемещать не только сами по себе, но и родительскими узлами в SceneTree. Поэтому перемещение родительских узлов также должно происходить только во время физических тиков.
Выберите тактовую частоту физики
При использовании интерполяции физики рендеринг отделяется от физики, и вы можете выбрать любое значение, подходящее для вашей игры. Вы больше не ограничены значениями, кратными частоте обновления монитора пользователя (для плавного игрового процесса при достижении целевого FPS).
В качестве приблизительного руководства:
Низкие тиковые частоты (10-30) |
Средние тиковые частоты (30-60) |
Высокие тиковые частоты (60+) |
|---|---|---|
Лучшая производительность процессора |
Хорошее физическое поведение в сложных сценах |
Хорошо с быстрой физикой |
Добавить некоторую задержку к вводу |
Подходит для игр от первого лица |
Подходит для гоночных игр |
Простое физическое поведение |
Примечание
Вы всегда можете изменить тиковую частоту в процессе разработки, это так же просто, как изменить настройки проекта.
Вызовите reset_physics_interpolation() при телепортации объектов
В большинстве случаев интерполяция — это то, что вам нужно между двумя физическими тиками. Однако есть одна ситуация, в которой она может не подойти. Например, когда вы изначально размещаете объекты или перемещаете их в новое место. В этом случае вам не нужно плавное перемещение между тем местом, где находился объект (например, началом координат), и исходным положением, вам нужно мгновенное перемещение.
Решение этой проблемы — вызвать функцию Node.reset_physics_interpolation. Эта функция устанавливает сохранённое внутри предыдущее преобразование объекта равным текущему преобразованию. Это гарантирует отсутствие смещения при интерполяции между этими двумя равными преобразованиями.
Даже если вы забудете это сделать, в большинстве случаев это не станет проблемой (особенно при высоких тикрейтах (tick rates)). Это можно легко оставить на этапе полировки игры. Худшее, что может случиться, — это полоса движения в течение примерно одного кадра при перемещении — вы сразу поймёте, когда это понадобится!
На самом деле существует два способа использования reset_physics_interpolation():
Старт с места (например, игрок)
Установить начальное преобразование
Включите
reset_physics_interpolation()
Предыдущее и текущее преобразования будут идентичны, что приведет к отсутствию начального движения.
Движущееся начало (например, маркер)
Установить начальное преобразование
Включите
reset_physics_interpolation()Немедленно установить ожидаемое преобразование после первого тика движения
Предыдущее преобразование станет начальной позицией, а текущее преобразование будет действовать так, как будто такт симуляции уже пройден. Это немедленно начнёт движение объекта, а не будет сопровождаться задержкой в течение такта.
Важно
Убедитесь, что вы задаете преобразование и вызываете reset_physics_interpolation() в правильном порядке, как показано выше, в противном случае вы увидите нежелательные "полосы".
Советы по тестированию и отладке
Даже если вы собираетесь запустить физику на скорости 60 TPS, чтобы тщательно протестировать интерполяцию и добиться максимально плавного игрового процесса, настоятельно рекомендуется временно установить частоту физических тиков на низкое значение, например 10 TPS.
Игровой процесс может работать не идеально, но он должен помочь вам легче определить случаи, когда следует вызывать Node.reset_physics_interpolation, или когда следует использовать собственную интерполяцию, например, для Camera3D. После исправления этих случаев можно вернуть частоту тиков физики к желаемому значению.
Ещё одно важное преимущество тестирования с низкой частотой тиков заключается в том, что вы часто можете заметить, что другие игровые системы, синхронизированные с физическим тиком, создают глюки, которые, возможно, стоит обойти. Типичные примеры включают настройку значений смешивания анимаций, которые можно задать в _process() и интерполировать вручную.
Примечание
In 2D, the position of visible collision shapes shown by the option will take physics interpolation into account.
By contrast, in 3D, the position of visible collision shapes will not take physics interpolation into account. This means the visible collision shapes can appear to move less smoothly and appear slightly in front of the object's visual representation when the object is moving. This is not a bug, but a consequence of how physics interpolation is implemented in 3D.