Прототип симулятора
Всем привет, хочу рассказать вкратце о небольшом прототипе будущей игры про снег, в который уже можно погонять в браузере или на Windows (вероятно, в ближайшие минуты добавлю и мак). И немного о том, как это работает и какие приколы я узнал про Unity.
Итак, что мы имеем: заснеженную площадь, грузовик с ковшом и несколько деревьев. Задача: почистить снег, чтобы горожане могли зажечь огни на ёлках. В целом это просто медитативная игра, в которой мы катаемся туда-сюда по локации. Из управления только WASD/стрелки, при проигрыше игра сама перезапустит уровень. Всё очень просто.
Что под капотом
Это Unity6, что понятно по тому, что при запуске нет сплэша. В этой версии движка его можно выключить бесплатно, за что спасибо разработчикам. Я не стесняюсь Unity, но как же он бесил!
В игре почти нет моделей: деревья и фонари я как обычно взял из другого проекта, но у меня не было грузовика, так что пришлось его по-быстрому склепать.
На всю кабину один материал, для которого запечены карты цвета, гладкости и нормали. Unity не умеет использовать карту гладкости из коробки, поэтому я сделал свой шейдер в Shafer Graph, который кочует из прототипа в прототип. Колёса я так же утащил из еще одного проекта.
Деревья строго лоуполи, а их листву обеспечивает шейдер, который генерит шум для прозрачности и цвета. Очень простое и симпатичное решение.
Снег! Самая прикольная фича прототипа, которую я планирую на досуге развивать и дорабатывать: это так же шейдер, который на основе маски двигает вершины плоскости с примерно 2к квадратами. Фактически, грузовик рисует под собой черные следы на белой текстуре, и на их месте вершины двигаются вниз.
Я почти сошел с ума, пока возился с этим шейдером, потому что, как выяснилось, в Shader Graph при работе с вершинами с помощью текстуры надо использовать ноду Sample Texture 2d LOD, а не просто Sample Texture 2d. Узнать об этом очень не просто, тот же ChatGPT разницу не понимает. Если это не учесть, просто не сможешь соединить ноды из-за разницы в типах. Ужасно бесит!
Также я узнал, что метод hit.textureCoord чудесным образом работает в редакторе, но не в билде, если, конечно, для меша, с которым он взаимодействует, не выставлен флаг Read/Write. Иначе он всегда отдает вектор 0,0.