2D Параллакс

Введение

Параллакс это эффект который используется для симуляции глубины текстурами, двигающимися на различных скоростях относительно камеры. Godot предоставляет узел Parallax2D для достижения этого эффекта. Это все же может быть непросто, так что эта страница предоставляет описания некоторых свойств и описания исправления распространенных ошибок.

Примечание

На этой странице описано, как использовать Parallax2D, который рекомендуется использовать для узлов ParallaxLayer и ParallaxBackground.

Начало работы

Узел параллакса поддерживает добавление узлов, которые визуализируют объекты как дочерние элементы, поэтому вы можете использовать один или несколько узлов для создания каждого слоя. Для начала разместите каждый узел или узлы, которые вы хотите прокручивать, независимо как дочерний элемент их собственного узла параллакса. Убедитесь, что верхний левый угол используемых текстур находится на пересечении (0, 0), как на изображении ниже. Смотрите раздел о positioning, чтобы узнать, почему это важно.

../../_images/2d_parallax_size_viewport.webp

В сцене выше используется одна подготовленная текстура для верхних облаков в Sprite2D, но вы можете с таким же успехом использовать несколько разнесенных узлов для составления слоя.

Шкала прокрутки

Основой эффекта параллакса является свойство scroll_scale. Оно работает как множитель скорости прокрутки, позволяя слоям перемещаться с другой скоростью, чем камера для каждого набора осей. Значение 1 заставляет узел параллакса прокручиваться с той же скоростью, что и камера. Если вы хотите, чтобы изображение смотрело дальше при прокрутке, используйте значение ниже 1, а 0 полностью останавливает его. Если вы хотите, чтобы что-то отображалось ближе к камере, используйте значение выше 1, заставив его прокручиваться быстрее.

Сцена выше состоит из пяти слоев. Некоторые хорошие значения scroll_scale могут быть:

  • (0.7, 1) - Лес

  • (0.5, 1) - Холмы

  • (0.3, 1) - Нижние облака

  • (0.2, 1) - Высокие облака

  • (0.1, 1) - Небо

На видео ниже показано, как эти значения влияют на прокрутку в игре:

Бесконечное повторение

Parallax2D обеспечивает бонусный эффект, который придает текстурам иллюзию бесконечного повторения. repeat_size сообщает узлу о необходимости привязывать свое положение вперед или назад, когда камера прокручивается на заданное значение. Этот эффект достигается путем добавления одного повтора ко всем дочерним элементам холста, смещенным на значение. Пока камера прокручивается между изображением и его повтором, она невидимо привязывается назад, создавая видимость зацикленного изображения.

../../_images/2d_parallax_scroll.gif

Поскольку это деликатный эффект, незнакомые пользователи могут легко ошибиться в настройке. Давайте рассмотрим «как» и «почему» нескольких распространенных проблем, с которыми сталкиваются пользователи.

Некорректное масштабирование

С эффектом бесконечного повторения проще всего работать, когда у вас есть изображение, разработанное для бесшовного повторения и имеющее тот же размер или больше, чем область просмотра до установки repeat_size. Если вы не можете получить ресурсы, разработанные для этой задачи, есть некоторые другие вещи, которые вы можете сделать, чтобы лучше подготовить свое изображение в отношении размера.

Вот пример текстуры, которая слишком мала для своего окна просмотра:

../../_images/2d_parallax_size_bad.webp

Мы видим, что размер области просмотра составляет 500x300, но текстура — 288x208. Если мы установим repeat_size на размер нашего изображения, эффект бесконечного повторения не будет прокручиваться должным образом, поскольку исходная текстура не покрывает область просмотра. Если мы установим repeat_size на размер области просмотра, у нас будет большой зазор. Что мы можем сделать?

Уменьшить область просмотра

Самый простой ответ — сделать область просмотра такого же размера или меньше, чем ваши текстуры. В Настройки проекта > Дисплей > Окно измените настройки Ширина области просмотра и Высота области просмотра в соответствии с вашим фоном.

../../_images/2d_parallax_size_viewport.webp

Масштаб Parallax2D

Если вы не стремитесь к идеальному стилю или не против небольшой размытости, вы можете выбрать больший масштаб текстур, чтобы они соответствовали вашему экрану. Установите scale для Parallax2D, и все дочерние текстуры будут масштабироваться вместе с ним.

Размер узлов-потомков

Подобно масштабированию Parallax2D, вы можете масштабировать ваши узлы Sprite2D, чтобы они были достаточно большими, чтобы покрыть экран. Помните, что некоторые настройки, такие как Parallax2D.repeat_size и Sprite2D.region_rect не учитывают масштабирование, поэтому необходимо настроить эти значения на основе масштаба.

../../_images/2d_parallax_size_scale.webp

Зацикливание текстур

Вы также можете начать с правильного подхода, подготовив дочерние узлы на более раннем этапе процесса. Если у вас есть Sprite2D, который вы хотите повторить, но он слишком мал, вы можете сделать следующее, чтобы повторить его:

Ниже вы можете видеть, что повторение изображения дважды делает его достаточно большим, чтобы закрыть весь экран.

../../_images/2d_parallax_size_repeat.webp

Некорректное позиционирование

Часто можно увидеть, как пользователи ошибочно устанавливают все свои текстуры по центру (0,0):

../../_images/2d_parallax_single_centered.webp

Это создает проблемы с эффектом бесконечного повторения и должно быть исключено. «Бесконечный повторяющийся холст» начинается с (0,0) и расширяется вниз и вправо до размера значения repeat_size.

../../_images/2d_parallax_single_expand.webp

Если текстуры центрированы на пересечении (0,0), бесконечно повторяющееся полотно покрыто лишь частично, поэтому оно повторяется лишь частично.

Поможет ли увеличение repeat_times исправить эту ситуацию?

Увеличение repeat_times технически сработало бы в некоторых сценариях, но это решение методом перебора, а не та проблема, которую оно призвано решать (мы рассмотрим это немного позже). Лучшим решением будет понять, как работает эффект повтора, и настроить текстуры параллакса соответствующим образом для начала.

Сначала проверьте, не перетекают ли какие-либо текстуры на отрицательные части холста. Убедитесь, что текстуры, используемые в узлах параллакса, помещаются внутри "бесконечного повторяющегося холста", начинающегося с (0,0). Таким образом, если Parallax2D.repeat_size задано правильно, это должно выглядеть примерно так, с одним единственным циклом изображения того же размера или больше, чем область просмотра:

../../_images/2d_parallax_repeat_good_norect.webp

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

../../_images/2d_parallax_repeat_good.webp

Если изображение расположено вдали от «бесконечно повторяющегося холста», то, когда камера достигает желтого прямоугольника, половина изображения обрезается, прежде чем оно перейдет вперед, как показано на изображении ниже:

../../_images/2d_parallax_repeat_bad.webp

Смещение прокрутки

Если ваши текстуры параллакса уже работают правильно, но вы предпочитаете, чтобы они начинались в другой точке, Parallax2D поставляется со свойством scroll_offset, используемым для смещения начала бесконечного повторяющегося холста. Например, если ваше изображение имеет размер 288x208, установка scroll_offset на (-144,0) или (144,0) позволяет ему начинаться на полпути через изображение.

Количество повторений

В идеале, следуя этому руководству, ваши текстуры параллакса будут достаточно большими, чтобы покрыть экран даже при уменьшении масштаба. До сих пор у нас была идеально подходящая текстура 288x208 внутри области просмотра 288x208. Однако, когда мы уменьшаем масштаб, устанавливая Camera2D.zoom на (0.5, 0.5), возникают проблемы:

../../_images/2d_parallax_zoom_single.webp

Несмотря на то, что все правильно установлено для области просмотра на уровне масштабирования по умолчанию, уменьшение масштаба делает ее меньше области просмотра, нарушая эффект бесконечного повторения. Вот где repeat_times может помочь. Установка значения 3 (один дополнительный повтор сзади и спереди) теперь достаточно велика для размещения эффекта бесконечного повторения.

../../_images/2d_parallax_zoom_repeat_times.webp

Если бы эти текстуры должны были повторяться по вертикали, мы бы указали значение y для repeat_size. repeat_times автоматически добавил бы повторение сверху и снизу. Это только горизонтальный параллакс, поэтому он оставляет пустой блок сверху и снизу изображения. Как нам решить эту проблему? Нам нужно проявить креативность! В этом примере мы растягиваем небо выше, а спрайт травы ниже. Теперь текстуры поддерживают нормальный уровень масштабирования и уменьшение до половинного размера.

../../_images/2d_parallax_zoom_repeat_adjusted.webp

Split screen (разделенный экран)

Большинство руководств по созданию игры с разделенным экраном в Godot начинаются с написания небольшого скрипта для назначения Viewport.world_2d первого SubViewport второму, чтобы у них был общий дисплей. Часто возникают вопросы о том, как разделить эффект параллакса между обоими экранами.

Эффект параллакса имитирует перспективу, перемещая позиции различных текстур относительно камеры. Это, понятно, проблематично, если у вас несколько камер, потому что ваши текстуры не могут находиться в двух местах одновременно!

Этого все еще можно достичь путем клонирования узлов параллакса во второй (или третий, или четвертый) SubViewport. Вот как выглядит настройка для игры двух игроков:

../../_images/2d_parallax_splitscreen.webp

Конечно, теперь оба фона отображаются в обоих SubViewports. Мы хотим, чтобы каждый параллакс отображался только в соответствующем ему viewport. Этого можно добиться, выполнив следующие действия:

  • Оставьте все узлы параллакса со значением по умолчанию visibility_layer, равным 1.

  • Установите для первого SubViewport canvas_cull_mask только слои 1 и 2.

  • Сделайте то же самое для второго SubViewport, но используйте слои 1 и 3.

  • Дайте вашим узлам параллакса в первом SubViewport общего родителя и установите его visibility_layer на 2.

  • Сделайте то же самое для узлов параллакса второго SubViewport, но используйте слой 3.

Как это работает? Если элемент холста имеет visibility_layer, который не соответствует canvas_cull_mask SubViewport, он скроет всех дочерних элементов, даже если они соответствуют. Мы используем это в своих интересах, позволяя SubViewports обрезать рендеринг узлов параллакса, родительский элемент которых не имеет поддерживаемого visibility_layer.

Предпросмотр в редакторе

До версии 4.3 рекомендовалось размещать каждый слой в собственном ParallaxBackground, включать свойство follow_viewport_enabled и масштабировать отдельный слой. Этот метод всегда был сложным для правильного выполнения, но его все еще можно реализовать, используя CanvasLayer вместо ParallaxBackground.

Примечание

Еще одна рекомендация - KoBeWi's "Parallax2D Preview" addon. Он предоставляет несколько различных режимов предварительного просмотра и очень удобен!