Что такое коллизия в играх

Box2d: анатомия коллизий

Что такое коллизии?

В Box2D принято считать, что друг с другом сталкиваются тела, однако на самом деле при расчете коллизий используются фикстуры (fixtures, переводы слова существуют, но я не уверен, есть ли среди них устоявшийся). Объекты могут сталкиваться разными способами, поэтому библиотека предоставляет большое количество уточняющей информации, которая может быть использована в игровой логике. Например, вы можете захотеть узнать следующее:

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Все настроено таким образом, чтобы нижняя часть треугольника столкнулась с верхним углом квадрата. Тонкости реализации этого процесса выходят за рамки статьи — основное внимание уделим тому, какую информацию можно извлечь на каждом этапе столкновения. Если есть желание самостоятельно запустить предлагаемый пример, исходный код прилагается.

Получении информации о столкновении

Информация о столкновении содержится в объекте типа b2Contact. Из него можно узнать, какие именно фикстуры сталкиваются, и определить их положение и направление результирующих импульсов. Существует два способа получения объектов b2Contact в Box2D. Первый — перебрать текущий список контактов каждого тела объекта, второй — использовать слушатель контактов. Рассмотрим каждый из них, чтобы дальше было понятнее, о чем идет речь.

Проверка списка контактов

В любой момент можно перебрать все контакты мира (имеется в виду b2World)

или получить контакты тела определенного объекта

Если выбран этот подход, очень важно помнить, что наличие контакта в этих списках не означает, что фикстуры соприкасаются — это значит только, что пересекаются их AABB. Если требуется убедиться, что контактируют сами фикстуры, воспользуйтесь методом IsTouching(). К этому вопросу мы еще вернемся.

Слушатели контактов

Проверка списка контактов становится неэффективной в ситуациях, когда столкновения происходят часто и в больших количествах. Устанавливая слушателей контактов, вы отдаете поручение Box2D сообщать, когда происходит что-то интересное, вместо того, чтобы вручную следить за началом и завершением столкновений. Слушатель контактов — это объект класса b2ContactListener, часть функций которого замещается при необходимости.

Должен заметить, что в зависимости от ситуации, некоторые события дают нам не только объект b2Contact. В процессе выполнения функции Step, когда Box2D определяет, что произошел контакт, он выполняет обратный вызов определенных функций слушателя, чтобы уведомить вас. Практическое использование «обратных вызовов при коллизиях» рассматривается в отдельной статье. Здесь мы все внимание сосредоточим на том, что можно узнать, обрабатывая события столкновений.

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

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

Когда происходит обход списка контактов определенного объекта, возможно, одна из фикстур коллизии известна, но если используется слушатель контактов, придется полностью положиться на эти функции, чтобы понять, что с чем сталкивается. Четко заданного порядка фикстур не существует, так что часто приходится устанавливать пользовательские данные (user data), чтобы понять, какому именно объекту принадлежит фикстура или тело. Располагая объектом фикстуры, можно воспользоваться методом GetBody(), чтобы получить ссылку на тело.

Столкновение шаг за шагом.

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

Начнем с ситуации, когда AABB фикстур не пересекаются, так мы сможет проследить историю полностью. Кликните флажок «AABBs», чтобы увидеть фиолетовые прямоугольные области вокруг каждой фикстуры.

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

AABB фикстур начинают перекрываться

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

Результат: контакт существует, но IsTouching() возвращает ложь

Продолжаем симуляцию, пока не пересекутся непосредственно фикстуры…

Фикстуры начинают пересекаться.

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

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

Шаг n
Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Шаг n+1 (не bullet-объекты)
Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

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

Шаг n+1 (треугольник — bullet-объект)
Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Bullet-тела, расходуют больше процессорного времени на расчеты и для большинства приложений не требуются. Просто помните о том, что при обычных настройках, иногда коллизии могут пропускаться — в нашем примере, если бы треугольник двигался достаточно быстро, он мог бы пролететь сквозь угол квадрата, не инициировав столкновения. Если у вас есть очень быстро перемещающиеся тела, контакты которых не должны пропускаться, например, мммм… пули 🙂 тогда их нужно объявлять как bullet-объекты. Дальнейшее изложение будет вестись для не-bullet-тел.

Точки столкновения и нормаль

К этому моменту в нашем контакте присутствует реальное соприкосновение, что дает возможность ответить не некоторые вопросы в начале статьи. Для начала давайте получим нормаль и точку касания. Предполагается, что приведенный далее код вызывается или из метода BeginContact слушателя контактов или из вашего метода после предварительного получения контакта из списка.

Объект контакта содержит информацию о коллизии в локальных координатах тел сталкивающихся объектов, а это не совсем то, что нам нужно. Однако можно запросить у контакта более полезную структуру b2WorldManifold, которая содержит позицию коллизии в мировых координатах.

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Полученные точки будут использованы Box2D для расчета реакции на столкновение для вычисления импульса, который направит фикстуры в противоположные стороны. Это будут неточные места соприкосновения фикстур (если только вы не использовали bullet-объекты), хотя на практике их обычно достаточно для расчетов столкновений в игровой логике.

Далее рассмотрим нормаль коллизии, которая направлена от фикстуры A к B:

Похоже на то, что для этого столкновения самый быстрый способ избавиться от перекрывающихся объектов, это оттолкнуть угол треугольника вверх и влево, а квадрата — вниз и вправо. Хотелось бы обратить ваше внимание на то, что нормаль — это просто направление, она не привязана ни к какой точке контакта — я изобразил ее проходящей через points[0] для удобства.

Важно также помнить, что нормаль столкновения не определяет угол между фикстурами (ведь треугольник двигается вообще горизонтально) — она лишь задает направление, следуя которому быстрее всего компенсируется перекрытие объектов. Например, представьте, что треугольник двигается немного быстрее, и перекрытие выглядит так:

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Тогда самый быстрый способ разделить фикстуры — оттолкнуть треугольник вверх и вправо. Так что использовать нормаль для расчета угла между объектами нецелесообразно. Если требуется узнать направления, по которым будут разделяться фигуры, можно воспользоваться следующим кодом:

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

Также нужно заметить, что не при каждом столкновении будет именно две точки коллизии. Я намерено остановился на достаточно сложном примере, когда перекрываются два угла многоугольников, но чаще бывает только одна такая точка. Вот несколько примеров столкновений, для которых достаточно одной точки

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Итак, только что мы рассмотрели, как определить точки и нормаль коллизии, на основе которых Box2D будет рассчитывать реакцию, направленную на компенсацию перекрытий. Теперь вернемся к последовательности событий.

Реакция на столкновение

( (b2Contact::Update, b2Island::Report))
Шаг_столкновения

Шаг_столкновения + 1
Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Шаг_столкновения + 1
Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Когда фикстуры перекрываются, реакция Box2d по умолчанию — приложить импульс к каждой из них, чтобы направить в разные стороны. Однако это не всегда удается сделать за один шаг моделирования. Как показано на рисунках для нашего примера, две фикстуры будут перекрываться на протяжении трех шагов, пока отскок не состоится, и они окончательно не разделятся.

В это время мы можем вмешаться и настроить поведение модели, как нам захочется. Если используется подход со слушателем контактов, методы PreSolve и PostSolve будут вызываться на каждом шаге, пока фикстуры перекрываются, давая возможность модифицировать контакт перед тем, как он будет обработан стандартными средствами реакции на коллизию (PreSolve), и узнать, какие импульсы были приложены Box2D (PostSolve)

Для большей наглядности приведу вывод printf, которая помещена в в функцию Step и каждый метод слушателя контактов:

Результат: PreSolve and PostSolve вызываются несколько раз

PreSolve and PostSolve

Оба эти метода получают в качестве параметра указатель на b2Contact, так что мы имеем доступ к той же информации о точках и нормалях, что и в BeginContact. PreSolve дает на возможность изменить характеристики контакта перед расчетом реакции на столкновение и даже отменить реакцию полностью. PostSolve позволяет получить информацию о вычисленной реакции.

В PreSolve можно сделать следующие настройки объекта контакта:

Вызов SetEnabled(false) деактивирует контакт, значит, реакция на столкновение просчитываться не будет. Это может понадобиться, когда необходимо временно позволить объектам пролетать друг сквозь друга. Классический пример — односторонняя стена или платформа, когда игрок может пройти сквозь обычно непроходимый объект при определенных условиях, которые можно проверить только во время выполнения — например, позиция игрока или направление его движения.

Важно помнить, что на следующей итерации контакт снова активируется, так что если нужно отключить его на продолжительное время, придется делать это на каждом шаге.

Кроме ссылки на контакт, PreSolve содержит второй параметр, из которого можно получить характеристики коллизии (точки и нормаль) с предыдущего шага моделирования. Если кто-то знает, зачем это может пригодиться — расскажите мне 😀

PostSolve вызывается после того, как реакция на столкновение была рассчитана и применена. У метода есть второй параметр, содержащий информацию о приложенном в результате импульсе. Обычно он используется для проверки, не превысила ли реакция некоторое пороговое значения, в результате чего объект можно разрушить и т.п. В статье » sticky projectiles» содержится пример использования функции PostSolve для определения, должна ли стрела застревать в мишени.

Возвращаемся к сценарию столкновения

Фикстуры больше не перекрываются

(b2Contact::Update)
AABB все еще перекрываются, так что контакт пока остается в соответствующих списках мира и тела.

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

(увеличенный масштаб)
Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

AABB фикстур не перекрываются

(b2ContactManager::Collide)
Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Результат: контакт удаляется из списка контактов мира и тела.

Метод EndContact получает указатель на b2Contact, когда фикстуры уже не соприкасаются, так что в нем уже не содержится актуальной информации. Тем не менее EndContact является неотъемлемым элементом слушателя контактов, так как позволяет контролировать, когда игровые объекты покидают зону соприкосновения.

Источник

Game Engine своими руками #8: Коллизии

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

Коллизии играют одну из первых ролей в устройстве игрового мира. Моделирование физического взаимодействия игровых объектов целиком и полностью основано на обработке коллизий. Очень часто мы сталкиваемся с проблемами определения пересечения двух объектов: если это шутер нам требуется определить, попала ли пуля во врага, если это гонка, то нас интересует взаимодействие колес автомобиля с дорогой, в бильярде мы рассматриваем столкновение шаров. Существует огромное количество различных типов коллизий, равно как и способов их обнаружения. Я начну с рассмотрения самых простых случаев, а ты проникайся, потому что такого скопления ценной инфы ты больше ни где не найдешь 😉

Пересечение двух сфер выявляется очень просто: мы находим расстояние между центрами сфер и если это расстояние больше суммы радиусов сфер, то сферы не пересекаются.

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Расстояние между двумя точками находится по школьной формуле:

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Здесь нам нужно найти расстояние от центра сферы до плоскости и сравнить его с радиусом сферы. Расстояние от точки до плоскости ищется по следующей формуле:

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Не барское это дело рассказывать про уравнение плоскости, но все же напомню, что любая плоскость определяется уравнением первой степени:

Подставив в первое уравнение, получаем:

Для упрощения вычислений бывает удобно заранее нормировать уравнение плоскости, т.е. поделить все коэффициенты (A, B, C, D) на длину нормали, т.е. на sqrt(A^2 + B^2 + C^2), тогда расстояние от точки до плоскости превратится в скалярное произведение:

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Аналогично двум предыдущим случаям, для определения пересечения прямой и сферы нам нужно найти расстояние от центра сферы до прямой и сравнить его с радиусом сферы.

Зная координаты (x0, y0, z0) точки лежащей на прямой и радиус-вектор (l, m, n) задающий направление прямой, можно записать параметрические уравнения прямой:

x = x0 + lt; y = y0 + mt; z = z0 + nt;

Очевидно, что расстояние от точки M(x*, y*, z*) до прямой есть расстояние от точки М до точки N пересечения прямой и перпендикулярной ей плоскости проведенной через
M.

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Плоскость перпендикулярная прямой и проходящая через точку M задается уравнением:

Подставив параметрические уравнения прямой в уравнение плоскости, найдем значение параметра t определяющего координаты точки N пересечения прямой и плоскости:

Если заранее нормировать вектор (l, m, n), то уравнение примет вид:

Подставив теперь это значение параметра t в параметрические уравнения прямой, найдем координаты точки N. После чего будет нетрудно найти расстояние между точками M и N.

Очевидно, что для определения пересечения сферы и отрезка недостаточно найти расстояние от центра сферы до прямой, которой принадлежит отрезок (см. рис.) нужно еще убедиться, что точка N принадлежит самому отрезку.

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

x = x1 + lt; y = y1 + mt; z = z1 + nt;

Это один из самых простых для обнаружения видов коллизий. Допустим у нас есть отрезок MN заданный двумя точками: M(x1, y1, z1) и N(x2, y2, z2) и плоскость заданная точкой (x0, y0, z0) и единичной нормалью (l, m, n), нужно охарактеризовать их взаимное расположение.

Уравнение плоскости запишется в виде:

lx + my + nz = lx0 + my0 + nz0

Найдем расстояние от каждого из концов отрезка до плоскости, по вышеописанной формуле, опустив знак модуля, получим для расстояние от M до плоскости:

Расстояние от N до плоскости:

Мы не стали учитывать знак модуля по следующим соображениям. Если принять, что направление нормали плоскости определяет внешнюю сторону плоскости, то знак этих выражений позволяет сказать по какую сторону от плоскости лежит точка. Например, если dist1 больше 0, то точка M лежит перед плоскостью, а если меньше 0, то позади. Таким образом, учитывая все вышесказанное, можно сделать следующий вывод: если знаки выражений dist1 и dist2 равны, то оба конца отрезка лежат по одну сторону от плоскости и следовательно отрезок плоскость не пересекает. Если же знаки различны, т.е. dist1*dist2 ASize[i]/2 + BSize[i]/2)
return 0;
>

Что такое коллизия в играх. Смотреть фото Что такое коллизия в играх. Смотреть картинку Что такое коллизия в играх. Картинка про Что такое коллизия в играх. Фото Что такое коллизия в играх

Чтобы определить пересекаются ли OBB’ы или нет, мы должны спроецировать их на некоторую ось и проверить пересекаются ли проекции. Теорема о «разделяющих осях» (Separating Axis Theorem)гласит, что существует только 15 потенциальных разделяющих осей, спроецировав OBB’ы на которые можно однозначно выявить наличие коллизии. Этими осями являются шесть локальных осей (по три для каждого OBB’а) и девять их векторных произведений. Чтобы нам было легче проецировать OOB’ы на оси, преобразуем один из OBB’ов в координатную систему другого с помощью матрицы преобразований (см. листинг)

typedef struct <
vec3_t pos; // координаты центра
vec3_t size; // размеры
vec3_t axis[3]; // локальные оси
> obb_t;

bool OBBsOverlap (obb_t a, obb_t b)
<
vec3_t a, b; // размеры уменьшенные вдвое (радиусы)
vec3_t v, T;
float rmatrix[3][3];
float ra, rb, t;
int i, j;

// делим размеры пополам
a[0] = a.size[0]/2;
a[1] = a.size[1]/2;
a[2] = a.size[2]/2;

b[0] = b.size[0]/2;
b[1] = b.size[1]/2;
b[2] = b.size[2]/2;

//
// преобразуем B в систему координат первого OBB’а
//

VectorSubtract (b.pos, a.pos, v);

T[0] = DotProduct (v, a.axis[0]);
T[1] = DotProduct (v, a.axis[1]);
T[2] = DotProduct (v, a.axis[2]);

// строим матрицу преобразования
for( i=0 ; i ra + rb ) return 0;
>

// на оси B
for( i=0 ; i ra + rb) return 0;
>

// 9 векторных произведений

// если до сих пор не вышли, то боксы пересекаются
return 1;
>

Источник

Проработка окружения в геймдеве: собираем первую игровую сцену

Финальная статья из цикла «Арт» для начинающих разработчиков — наполняем деталями локации и полируем сцены.

Автор: Александр Новиков. По образованию программист, но в геймдев попал как концепт-художник. Потом переучился на 3D-художника и пришел в Pixonic. Работал над War Robots и другими проектами компании. Стал техлидом, и сейчас занимается прототипами игр.

В предыдущей статье о 3D-моделировании мы учились создавать уникальные внутриигровые объекты. Разобравшись с принципами создания арта, можно заменять им «серые кубики» из прототипа, чтобы потихоньку готовиться к первому релизу. Следующий этап — объединить объекты в одну сцену.

В конце статьи — последнее в этом цикле домашнее задание для конкурса работ. Выполните его, чтобы выиграть лимитированное издание Kingdom Hearts III PS4 Pro Bundle и прокачать скилл геймдизайнера.

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

Теперь перечислим несколько моментов, которым нужно уделить внимание, когда собираешь сцену. Обычно она включает в себя источники света, террейн (ландшафт), пропсы и геометрию, а также геймплейную логику (скрипты на объектах, триггеры).

Точки интереса. Игровой мир не должен быть однообразным. Например, если в игре можно долго идти по джунглям, хорошо бы поставить на пути игрока древнюю пирамиду, упавший самолет и тому подобное. Иначе игроку может быстро надоесть, и он выйдет из игры.

Rise of the Tomb Raider

Пройдитесь по сцене — нет ли там слишком длинных и однообразных маршрутов, не кажется ли сцена слишком «пустой» местами?

Проработка окружения. Обратите внимание, какими предметами заполнены сцены в хорроре Alien Isolation. Трубы, решётки, дым, который отбрасывает пугающие тени от правильно расположенного источника света — всё это создаёт атмосферу страха, даже когда рядом нет противника.

Ещё раз вернитесь к сеттингу и жанру игры, к мудбордам и референсам — обратите внимание на мелкие детали. Задумайтесь, передаёт ли ваша локация нужную атмосферу.

Акценты. Ещё одна задача при разработке игры — расставить акценты. Ключевые элементы геймплея должны быть выделены, а фон не должен отвлекать внимание от процесса.

Например, важнее сначала разглядеть цель и противников, а не лежащий на полу лут. А факелы в подземелье, которые можно зажечь, должны быть видны даже в темноте. Всё это — акценты, чтобы визуальная информация помогала лучше ориентировался в мире игры.

Может показаться, что все элементы и объекты на скриншоте выше расставлены незамысловато. Но присмотритесь — маркер цели отлично читается на общем фоне, хотя это просто элемент UI. Общий фон не забирает на себя много внимания — он приглушен туманом и имеет минимальную контрастность. Ближний фон, наоборот, весьма контрастный. А ёлки, камни и платформа показывают понятный игроку путь до цели.

Составьте список ключевых элементов в вашей игре и убедитесь, что им уделено достаточно внимания, а второстепенные объекты не перетягивают внимание. Игрок всегда должен понимать, что ему делать.

Свет. Он должен гармонично подчёркивать интерактивные детали на сцене. Кроме того, в играх свет часто устанавливается так, чтобы показывать дальнейший путь главного героя, как бы намекая куда двигаться дальше. Это работает, даже если игрок не осознаёт этого.

Ещё одна хорошая практика — детальнее продумывать светлые участки на уровне. Их стоит внимательно детализировать, наполняя интересными объектами. Участки в тени не требуют такой глубокой проработки и это может быть хорошим лайфхаком для инди-проекта с ограниченными ресурсами.

Обратите внимание на все интерактивные объекты на сцене — они должны быть отличимы от остальных. Стоит также прикинуть, что будет, если игрок не заметит их и просто пройдёт мимо.

Лаконичность. Не менее сложным бывает вовремя остановиться и не перегружать игровую сцену деталями. Когда объектов слишком много, игрок быстро устает от картинки.

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

Осталось понять, чем наполнить сцену, чтобы создать правильное настроение. Во-первых, есть общие рекомендации использования цветов. Во-вторых, вдохновение можно черпать из фильмов и других игр этого жанра.

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

Под цветом я имею ввиду палитры, которые используются в текстурах, преобладающие источники света (теплые или холодные) и цветокоррекцию. Например, на скриншоте ниже мы видим чистые светло-серые и тёмно-серые текстуры, спокойное нейтральное освещение и цветокоррекцию, которая даёт характерный зеленоватый оттенок.

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

Тестировать сцены и левел-дизайн так же важно, как идеи, механики и визуал. Для независимых разработчиков варианты собрать фидбек остаются теми же, что и в прошлых статьях: дать поиграть билд друзьям; завести свой YouTube-канал или странички в соцсетях, чтобы делиться ходом разработки и собирать комментарии; создать Discord-канал (или поискать чужие — там сидит много энтузиастов). Много фидбека можно собрать на Reddit, если не пугает английский, или на DTF.

Во время плейтестов просите обращать внимание на то, в каких местах стоит изменить геометрию уровня, чтобы играть было удобнее. Пусть игроки попытаются забраться туда, куда не следует, и в идеале — пройдут после плейтестов простую анкету: что понравилось и не понравилось, где было скучно, а где весело, что стоит улучшить, стали бы рекомендовать друзьям, что запомнилось больше всего, и так далее.

Также стоит проверить коллизии на всех объектах, чтобы игрок не смог попасть за пределы сцены. Коллизия — это упрощённая геометрия объекта, которая позволяет взаимодействовать с другими объектами: столкновения, выстрелы, навигация ИИ (противники должны обходить объекты с коллизией) и прочее. Например, если отключить коллизию в 3D-шутере, игрок просто провалится под землю — персонаж и поверхность не будут взаимодействовать, то есть сталкиваться.

Если в игре не используется освещение в реальном времени, обратите внимание на оптимизацию лайтмэпов — текстур, в которых хранится информация по освещению на сцене. Любой объект на сцене занимает в лайтмэпе своё UV-пространство, и совсем не круто, если незаметный камень заполнит четверть всей текстуры. Чем меньше места останется на лайтмэпе для значимых объектов, тем хуже на них запечётся освещение. Количество лайтмэп-текстур в игре ограничено, так что их надо использовать аккуратно.

Чтобы настроить лайтмэпы в Unity, раскройте вкладку Lightmaps в инспекторе объекта и нажмите на текстуре Open Preview. Откроется окно с общим лайтмэпом сцены, где жёлтым будет обозначен ваш пропс. Сразу видно, сколько места он занимает относительно других объектов.

Если встречаются артефакты в освещении или тенях, обязательно проверьте, что у объектов достаточно разрешения в лайтмэп-текстуре. В Unity за это отвечает параметр Scale In Lightmap. Дефолтное значение 1, а для малозаметных объектов можно поставить значение 0.5. Иногда, наоборот, приходится увеличивать это значение, когда свет запекается некорректно.

Здесь, подняв значение Scale In Lightmap c 1 до 1,6, мне удалось избавиться от «чёрного» камня после перепекания лайтмэпа.

После оптимизации ассетов, обратите внимание, чтобы не осталось белых засветов и полностью черных теней — это первые признаки несбалансированной картинки. В большинстве случаев объекты должны «читаться» даже в тени. Если какое-то пространство просто «залито» чёрным цветом, глаз воспринимает это как «провал» в окружении, как на примере с камнем выше.

Конечно, бывают исключения, особенно в 2D и инди-проектах. Всё зависит от вашего замысла.

Unepic. Темно, но тут своя атмосфера

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

После внесения всех правок по фидбеку, наступает очередь финального тестирования. Ещё раз проверяется геймплей на сцене: если всё корректно работает и пробегается — отлично. Но какие-то сложные баги обычно находят уже сами игроки в процессе и исправляются с апдейтами после релиза.

Перед релизом проекта надо провести финальную проверку арт-контента, в основном это касается ассетов и текстур. Конкретные значения тут зависят от выбранной платформы, но если говорить в целом, то для текстур проверяются разрешение и степень сжатия, а для ассетов — корректные настройки мешей. Например, чтобы у статичных объектов была выключена анимация.

Настраивать билды для мобильных платформ внутри движка лучше в начале или середине разработки, чтобы ошибки с компрессией текстур всплывали на ранних тестах. Но в процессе разработки не всегда получается настроить всё вовремя, поэтому перед финальным релизом необходимо пробежаться по контенту и всё проверить. Будет плохо, если где-то заваляется текстура маленького кристалла в разрешении 2k, а размер билда при этом вырастет на 5–10 Мбайт.

Итак, финальное задание на этот цикл, а приз — лимитированное издание Kingdom Hearts III PS4 Pro Bundle. Если вы уже выполнили задания из предыдущих статей, то будет совсем просто. Нужно вспомнить всё, что мы уже проходили, и собрать выполненные задания в одном письме:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *