Создаю лутер шутер в изометрии - Оружие, карта и инверсная кинематика
Идёт третья неделя разработки и после мучений у меня есть есть чем поделиться, ну и куда без небольшой статьи.
Освещение
Раньше, все комнаты были накрыты чёрной плоскостью для того что бы исключить влияние освещения сцены на ещё закрытые комнаты. Это решение хоть и исправляло проблему, но создавало новую, в виде невозможности рендера чего либо внутри этой самой комнаты.
После обдумываний как можно остановить распространение света вне комнаты источника освещения, я всё таки выдавил из себя новую идею.
Все комнаты были окружены стенами, у которых был выставлен нулевой alpha канал и убрана галочка alpha clipping, что отключило их отображение, НО! Не убрало их свойство блокировать свет.
Теперь любой источник в комнате может испускать свет через двери, но не использует для этого "невидимую часть".
в этом плане есть лишь одна ошибка, я использовал для невидимых стен кубы. Почему это ошибка? Куб имеет в 6 раз больше сторон чем обычная плоскость, потому теперь кол-во вершин для рендера в 6 раз больше чем с использованием обычных плоскостей. Это я пофикшу, но такой тупой косяк нужно было ещё придумать.
Инверсная кинематика
Игрок состоит из скелета и меша с весами. Изменение скелета, провоцирует изменение геометрии. Изначально всё изменение производилось через набор анимаций которые изменялись от параметров движения. Всё работает не плохо, пока у нас не появится оружие. У оружия есть своя анимация, каждый ствол имеет свои места для хвата и ко всему этому нужно присоединить руки и присоединить так, что бы это выглядело не стрёмно.
И вот сюда уже с двух ног залетает инверсная кинематика, которая позволяет нам управлять костями и настраивать их взаимодействие между друг другом.
В моём случае были испльзованы
- Multi rotation constraint - Применяет изменение вращения группы костей к целевой кости.
- Multi position constraint - Применяет изменение позиции группы костей к целевой кости.
- Two bone constraint - Контролирует группу костей так, что бы конец был направлен к нужной цели.
- Multi aim constraint - Поворачивает кость в направлении цели.
Все эти компоненты позволяют нам весьма тонко настроить изменение костей под различные ситуации.
Multi rotation constraint - используется для поворота оружия при движении спины игрока. Появляется необходимая нам тряски оружия при движении.
Multi position constraint - используется для изменения позиции оружия при поворотах плеча для плавного эффекта инерции при резком развороте игрока.
Two bone constraint - Прикрепляет руки к установленным точкам на оружии и плавно двигает их при перемещении оружия или его анимации.
Multi aim constraint - В связи с наличием анимации бега который постоянно пытается вращать торс игрока, приходится фиксировать его поворот на ~40% в сторону взгляда для отзывчивости управления.
Это буквально пару дней изучения этой системы, поэтому вероятно я делаю что то не так, но опять же будем изучать - будем смотреть.
Блик
Изначально хотел сделать по простому, белую плоскость с анимацией движения сверху вниз, но потом понял что в будущем изменю модели дверей и с наличем в них выступов и разделением элементов при анимации, подобная реализация будет выглядеть совсем жопно. Ну и как было в прошлый раз через пару минут обдумывания проблемы мой весьма тупой мозг выдал следующее - "ШЕЙДЕРЫ УФ БЛЯЯ" и я решил сделать такой шейдер:
- Получаем UV.
- Вращаем UV до нужного нам поворота.
- Делаем сдвиг через Tiling.
- Применяем полученный UV к ноде Rectangle.
- Настраиваем ширину и т.п.
- Изменяем Offset через анимацию (можно было через шейдер и Time, но лишняя потеря времени.)
Этот эффект работает для любой геометрии и с любой стороны. Эффект общий на все двери, но распространять его на определённые я не вижу смысла. Можно потом подумать где ещё можно использовать этот "блик", но пока мне видятся только двери.
Стрельба
Всё работает через систему пула, которую я написал ещё чёрт знает когда. Для людей несведующих, всё весьма просто.
Когда ты стреляешь, логичным вариантом было бы заспавнить снаряд, после попадания уничтожить его и заспавнить новый, но вот проблема. Такая реализация приведёт к большой трате процессорного времени, т.к создание новых объектов и их компонентов очень накладный процесс.
Поэтому базовой базой была принята система пулинга, которая вместо того что бы удалять и создавать новый объект, изначально генерирует какое то ко-во снарядов (к примеру 30), а далее берёт первый снаряд из очереди, выстреливает им, после попадания не удаляет, а скрывает и обнуляет все значения до исходного состояния, и как только потребуется новый снаряд, просто берёт первый скрытый и выстреливает им.
Для стрельбы использую тайлы с RigidBody и продолговатой текстурой, которую потом изменяю через шейдер и умножаю цвет на цвет, тем самым получаю hdr для свечения.
Траты при стрельбе 100 снарядов/с минимальны и находятся на уровне погрешности. На всех видосах в посте скорость стрельбы находится на уровне 10 снарядов/с .
Muzzle
Это дульная вспышка, т.е в момент когда происходит выстрел должна воспроизвестись анимация "огня". Думаю, ну на ассет сторе такое должно быть за бесплатно, т.к делать там нечего и тут я своими зоркими глазками замечаю стоимость в 10$ за 10 штук, т.е 1$ за 1 эффект.
Т.к я коммунист и не терплю эти буржуйские повадки, а не потому что я нищенка, мною встала быстрая реализация этого эффекта через sprite sheet анимацию.
Заходим в photoshop, делаем полоску и через равные промежутки делаем кадры этого эффекта
Заходим в движок -> sprite editor - slice -> и делим всё на прямоугольники с выставленным на точку источника огня пивотом.
Перетаскиваем спрайт на сцену, Unity автоматом генерит нам анимацию из кадров, а далее уже используем как нам нужно.
Я же захотел добавить к этому ещё свет от вспышки и дополнительно через анимацию включаю и отключаю источник света при стрельбе, что даёт весьма прикольный эффект.
Таким образом коммунистический режим ещё раз доказал своё превосходство над жалкими капиталистами.
Коммунизм - бесплатно.
Капитализм - 10$.
Выбор за вами.
Карта
Миникарта это конечно хорошо, но хотелось бы иметь возможность открыть полную версию и посмотреть где ты вообще находишься.
Крупная карта копирует миникарту и использует те же методы вставки новых комнат что и её младшая версия. Но теперь в отличии от старой версии, мы можем увидеть проходы из одной комнаты в другую и вот тут буду честен, мой мозг не придумал ничего лучше, чем по тупому вставлять доп спрайты по повороту дверей с этими проходами.
Выглядит конечно не плохо и справляется с поставленной задачей, но хочу придумать более логичный и правильный вариант, хоть вероятно придётся с ним помучиться.
Итог
Неделя как по мне прошла весьма продуктивно, можно было сделать ещё больше, но мои тупняки с инверсной кинематикой заняли весьма много времени. Следующим этапом будем Navmesh и первые противники, ну и конечно статейка.
* Вы должны понимать что делать всё именно так, может быть неправильно, т.к я сам ещё начинающий разработчик и считать это за правильную реализацию не стоит.
Весь прогресс опубликовываю на Discord сервере по Unity, если хотите то можете присоединиться к обсуждению или показать что то своё, сегодня как раз скриншотный субботник.
Спасибо за прочтение.