Skak. Девлог 1. Тени, покраска, анимации

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

Небольшой кликбейт
Небольшой кликбейт

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

Тени

Юра нарисовал новые спрайты, а я получил идею фикс — сделать «правильные» тени фигур, которые бы корректно отображались на клетках, даже если те чуть выше или чуть ниже уровня нуля.

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

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

Skak. Девлог 1. Тени, покраска, анимации

После этого создал камеру, которая подменяла спрайтам из нужного слоя материал на материал тени и получал что-то типа карты теней:

После этого нужно было написать шейдер для клеток, который бы накладывал на них тени. Сначала карта теней сдвигалась на Z координату (высоту) клетки, а потом просто накладывалась тень на основе скрин спейса. Помимо этого, так как камера ортогональная, шейдер еще и модифицировал Y координату, добавляя к ней «высоту». Был вариант повернуть камеру, но тогда начинались танцы с просчетом всего остального, и нам показалось, что это только усложнит все. По итогу получалась довольно интересно выглядящая тень:

Skak. Девлог 1. Тени, покраска, анимации

Шейдер для пола уже был сделан в шейдер лабе и выглядит вот так:

Да, может, вам неинтересно, но я очень доволен, потому что делаю первые шажки с шейдерами.
Да, может, вам неинтересно, но я очень доволен, потому что делаю первые шажки с шейдерами.

Покраска фигур

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

Сначала я попытался сделать так же и просто менять каждый из пяти цветов с помощью Replace Color Node. Единственное отличие, что теперь вместо цветов в материал передавался номер ряда и палитра с подбором цветов по рядам. Но тут возникло две проблемы:
1. Это очень немасштабируемо — под каждый из пяти цветов палитры приходилось писать целую ноду с кучей параметров
2. Оно просто не работало

Скорее всего проблема была в точности сравнения флоатов и, в попытках понять, в чем на самом деле была проблема, я просто придумал другое решение — более элегантное и удобное. Оно заключалось в том, чтобы брать канал цвета грейскейл текстуры как U координату (от UV) палитры и получилось вот так:

Skak. Девлог 1. Тени, покраска, анимации

Это упрощало вообще все и было очень красивым решением. По итогу получили красивые фигурки:

Skak. Девлог 1. Тени, покраска, анимации

Анимации

В юнити есть классный инструментарий для работы с анимациями, но он совершено неудобен, когда речь заходит о процедурной анимации, особенно поспрайтовой со скинами, как у нас. Чтобы стало чуть понятнее: вот есть у нас шахматный квадрат. Он бывает черный и светлый. Юра нарисовал анимацию разрушения под каждый цвет и нужно кадры анмимации сменять постепенно на основе игровых событий. Даже не анимации, а вот кадры по одному. И в одну сторону, слева-направо. Делать это в Animation Controller’е нам показалось громоздким, поэтому выбор кадра записан в коде ручками. А чтобы легко менять «скин» была сделана модель, которая хранила в себе одномерный массив спрайтов. А чтобы было удобнее пользоваться, я написал скрипт для Unity редактора (Editor), который на основе выделенных спрайтов создавал такую вот нарезку:

А затем в коде можно просто было выбрать нужную:

public void SyncSprite() { _spriteRenderer.sprite = spritesByType[(int) state.squareType].sprites[state.animationFrame]; }

Да, немного костыльно, ну а некостыльно как-то не вышло в юнити

Как-то так :)

48
13 комментариев

Комментарий недоступен

2
Ответить

Пасибо!

1
Ответить

Похорошела то как игра после Хакатона)

1
Ответить

Мор лайк игровые зарисовки, а не игра)

Ответить

Вот это поворот. Тоже делаю Chess Royale :)
https://dtf.ru/indie/717477-chess-royale-v2-0

Все равно конечно отличаются, но забавно. Удачи в разработке!

1
Ответить

Хорош, успехов и удачи, выглядит круто!!!
@Yuriy Gordeyev рисуешь???

Ответить