Григорий Дядиченко – Telegram
Григорий Дядиченко
2.82K subscribers
395 photos
160 videos
7 files
1.2K links
Разработчик игр, интерактивных стендов и интерактивной рекламы. Эксперт в области интерактивов и XR.

100+ проектов за 5 лет.

По вопросам сотрудничества писать: @it_bizdev
Реклама в канале: https://vk.cc/cNhGLE
Download Telegram
Какой красивый шейдер на параллакс маппинге 🤩

https://mobile.twitter.com/tomdns_/status/1044637213533892608
10
Пиксельарт

Многие любят фотореализм и графен, а мне как-то всегда больше нравилась стилизация. Ori, Hades, Crypt of the NecroDancer :) И бывают так же клёвые представители пиксель арта, тот же Narita Boy (очень стильная игра)

С пиксель артом есть одна проблема, хотя она и мелкая. Чтобы не было визуальных проблем нужно весьма специфично двигать камеру (собственно кратно пикселям) Удобно размер камеры делать таким и всю сетку координат, чтобы работать вообще с int значениями, а не с float. Тогда в целом ничего не будет мерцать :)

Ну и вот недавно вышел прикольный туториал на одном канале по VFX в стилистике пиксель арта :) https://youtu.be/JZDlCuIpq9I
Как мерить фпс?

В целом для любой более-менее серьёзной разработки нужны дебаг инструменты, которые открываются в рантайме. В мелких проектах я просто делаю скрытую панель, которую крайне маловероятно что найдёт пользователь (например 15 кликов быстрых на определённый текст в интерфейсе). В крупных проектах они вообще не идут в сборку, так как там есть dev, stage, prod билды, настроенные для них окружения и т.п. Собственно ряд инструментов ездит почти в каждый проект) Один из таких это https://github.com/Tayx94/graphy

Абсолютно гениальная вещь для мониторинга перфоманса) Ребята сделали очень крутой плагин) Он показывает фреймрейт, память, громкость звука. А так же всю информацию о тестируемом устройстве — просто ляпота :)
Fluent Design

Надо немного поговорить на тему UX в AR. У майкрософта есть старая классная концепция дизайна — Fluent Design. https://www.youtube.com/watch?v=vcBGj4R7Fo0 И одна её идея отлично подходит под дополненную реальность. В ней очень круто смотрится акрил :) (В прошлом году я даже написал статью с разбором, как его получить https://habr.com/ru/post/565662/ и репозиторием https://github.com/Nox7atra/UMOM )

Но что такого классного в акриле в AR? Ну на самом деле несколько пунктов.

1. Как и любой "фотореализм" он не имеет стиля — то есть универсален

Плюс фотореалистичной графики относительно стилизации в целом в том, что нельзя сказать "о, этот реализм — это марвел, а этот dc". Их можно разделить по настроению, по посту, по цветовой палитре и т.п. Но по сути визуально реализм есть реализм

2. Он подстраивается под любой фон

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

3. Он не отвлекает от самого AR

Центральным объектом в AR вряд ли является интерфейс, поэтому конечно кнопки отделены от фона благодаря фактуре, но в какой-то момент их проще перестать замечать, так как так или иначе они цвета фона. Есть трюки, как на акриле балансировать контрастность, если это вдруг зачем-то надо. Но обычно, как раньше говорилось: "Лучший интерфейс, это отсутствие интерфейса". Так что акрил это компромисс, так как при правильном использовании ты как минимум перестаёшь замечать наличие худа, как такового. И кажется что места на экране больше для самого центрального объекта

В целом в Fluent Design концепции было много интересных идей, жаль она конечно не развита с точки зрения гайдлайнов так, как тот же Material Design :)
Триггерный ИИ

Игровой ИИ — это очень глубокая тема, в ней можно прям закопаться. Конечные автоматы, Behavior Tree и многое другое. Комбинированные методы. Но я хочу рассказать об упрощённой задаче, так сказать для затравочки, которую мы решали в этом проекте https://foxsys.pro/beringia-game Это стенд на выставку, так что тут нет требования, чтобы ИИ был прям умным)

В целом есть базовое правило, когда вы выставляете игру на выставке, каком-то шоукейсе или другом мероприятии в идеале у неё должно быть два состояния: в неё кто-то играет или она играет сама в себя. Причём решений второго масса, самый простой из которых, когда игры никто не касается больше 1-2 минут, она переносится на старт и запускает ролик с записью геймплея. У нас же игра позволяла простенький мультиплеер на стенде, поэтому идея была просто. Нужен ИИ который:

1. Будет играть сам с собой и игроками
2. У него можно перехватить управление. На случай если кто-то решил зайти в игру, когда другие игроки играют. Чтобы не ждать пока "ИИ" доиграет
3. Будет играть каждый раз не одинаково. Плюс с ИИ всегда есть проблема баланса, чтобы в простой игре он не всегда выигрывал и у него был рассчитан диапазон набираемых очков

В подобном раннере — это было сделано довольно просто. Карта у нас заготовленная, хотя на бесконечной делалось это бы точно так же. По трассе просто расставляются триггеры с весами. Где вес определяет с какой вероятностью ИИ пойдёт в сторону и в какую. Если вдруг у кого-то нет, вот сниппет самого простого алгоритма расчёта взвешенной вероятности https://pastebin.com/aMCZup9V Добавив условие, что триггеры игнорируются, если пользователь нажал кнопку управления в течении последних 15 секунд, мы получаем перехват управления. Как игроком, так и ИИ при 15 секундном бездействии заберёт на себя управление, если кому-то скажем нужно срочно отойти и с кем-то поговорить

Причём важно понимать, что триггеры в данном случае — это всего лишь удобный инструмент для левел дизайна. В сущности ровно тоже самое можно было бы параметрически представить в виде сценария, где запуск сценариев зависит от пройденного игроком расстояния, и в момент перехода границы делается взвешенный выбор. То есть скажем таким образом не на триггерах, а сделав сценарий в виде графа решений, можно сделать ИИ для любой пошаговой игры скажем. Но как я и говорил, сам по себе ИИ это очень глубокая тема, так что потом разберём и другие примеры :)
👍2
Хоть и старенький, но классный туториал по эффекту из Dragon Ball
https://youtu.be/TR1xM1HMNQ8

Он отлично демонстрирует, что VFX это такая кросс экспертиза, где нужно немного уметь в несколько дисциплин вроде 3д моделирования, написания шейдеров и т.п. :)
🔥4
А пока можно посмотреть красивые картинки :)
DALL·E 2 (https://openai.com/dall-e-2/#demos)

Больше конечно похоже на первоапрельскую шутку, чем на что-то реальное, но появилось оно вроде не первого апреля) Какая-то просто безумная нейросеть (судя по картинкам) :)

Я скептик :) Так как за последние 7 лет я видел столько красивых роликов про технологии, что пока её нельзя потыкать, я ей не верю :) Но если оно действительно работает, как показано на сайте — it’s revolution Jonny :) Не скажу, что это «убьёт мир иллюстрации», как многие говорят. Так как всё же стиль соблюдать — нужен будет специальный человек по работе с этой нейросетью :) Но низкобюджетный сегмент для небольших клиентов — сильно подкосит :)

В общем подождёмс пока можно будет протестировать :)
🔥2
Кстати о Random

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

По сути мы берём интеграл от части кривой и получаем площадь под ней, что и считаем весом в наших вероятностях :) Что бывает нагляднее и проще, чем вбивать кучу весов, особенно если значений очень много и нужно "примерно так" :)
👍10
Rider Flow https://www.jetbrains.com/riderflow/

Просто шикарный плагин для Unity от JetBrains, как и многое от джетбрейнс :) В этом обзоре можно посмотреть на его фичи :) https://youtu.be/iUIjiKtILUc

Я же могу сказать, что я пробовал много IDE, и это всегда холиварная тема для программистов :) Кто-то любит вижак, кто-то вижуал студию код, кто-то до сих пор не смог выйти из Vim :) Я же уже 4 года как пересел на райдер с вижуал студии и он просто прекрасен. Но дело даже не в райдере, прекрасен не он, прекрасен решарпер. Основной причиной перехода 4 года назад стало то, что решарпер в вижуал студии дико тормозил, а в райдере просто летал :) Поэтому новая штука от брейнсов — это всегда круто :)
🔥6
Прикольный туториал по ретро эффекту. Не уверен конечно в подходе к пикселизации картинки, хотя можно все артефакты на стиль, и основной плюс этого метода, что рендерить такого размера кадр сможет любой калькулятор https://www.youtube.com/watch?v=3Ccu3UtiSdw

Я когда-то игрался с подобными трюками, но для другого. С рендером в отдельное RT. Для блума. Но это же классический скринспейс эффект скажете вы) И будете правы, даже в постпроцессинге есть, а так же куча его вариаций на просторах интернета. Базируется он всегда на блюре. Только вот он достаточно прожорлив на производительность. А задача была завести сай-фай сцену на телефоне за 7к рублей :) Ну а какой сайфай без блума? Самый быстрый придуманный трюк прост в своей гениальности. Все светящиеся объекты рендерились отдельной камерой с разрешением в 3 раза ниже оригинальной) Получался достаточный эффект для разрешения телефона за 7к рублей, и всё летало :) Собственно так же в RT с альфа каналом рендерился кадр со светящимися объектами, а сортировка не ломалась, так как в шейдерах информация о Z не отбрасывалась :)
Паттерн Наблюдатель

Я долго думал, какой пример сделать для этого паттерна. Применяется он повсеместно. Неважно знаете вы об этом или нет) Потому что, как только вы пишете что-то вроде public event Action вы автоматически делаете наблюдателя) Поэтому любой пример с явным определением интерфейса IObserver и IObservable как указано тут https://metanit.com/sharp/patterns/3.2.php мне казался высосанным из пальца :)

Самым ярким представителем использования паттерна наблюдатель являются ReactiveProperty из https://github.com/neuecc/UniRx В целом реактивная парадигма, даже в том же React.js во многом построена на идее того, что наблюдатель едет через наблюдателя. Всё на событиях, все друг друга оповещают, причём часто без прямых зависимостей)

В общем в юнити наблюдатель, как паттерн используется плюс минус постоянно. Вам нужно при обновлении счёта, обновлять UI панельку, делать отлетающий текст + записывать что-то в аналитику — вы делаете наблюдателя. Вам нужно при ударе наносить урон, списывать сустейн с оружия, а также писать в журнал событий что игрок за время в игре нанёс 100500 урона — вы делаете наблюдателя:)

Это такой паттерн, который очень часто удобен. И какой-либо конкретный пример получается либо неявным, либо слишком надуманным. Потому что сахар в шарпе это хорошо, но иногда он усложняет восприятие :) Может позде придумаю. Ну или кто может покажет, какой можно сделать пример с явным определением интерфейсов?

Прошлые разборы паттернов:
1. Команда — https://news.1rj.ru/str/dyadichenkoga/76
2. Декоратор — https://news.1rj.ru/str/dyadichenkoga/82
👍6🔥4
Тесты производительности

https://www.youtube.com/watch?v=d3kHuY99BW0 прикольный ролик, циферки это всегда классно и такие вещи смотреть любопытно. Автор молодец, что проделал такую работу, но этому тесту строго говоря — нельзя верить) Так как там столько нюансов на самом деле. Бенчмаркинг — это очень сложно) Можно посмотреть ролики Акиньшина на эту тему :)

Просто всегда показывая такие тесты производительности, помимо скриптинг бекенда нужно указывать платформу и железо, и число запусков. При этом указывать ещё максимальное, минимальное и среднее :) Потому что какие существуют нюансы :)

1. Во что компилируется код под платформу

Это прям далеко не всегда одно и тоже под разные платформы. Помню когда я ещё ходил по собесам мне несколько раз задавали вопрос про разницу между a + b + c и string.Concat(a, b, c) где abc это строки. Я надеюсь, что в современном юнити под все платформы разницы нет. Типа если коротко, тезис был в том, что явное задание конката лучше, так как конкат аллоцирует "abc", а суммирование "ab" и "abc". Я удивился, что компилятор умеющий разворачивать foreach в for не умеет обрабатывать такой случай. Пришёл домой, скомпилил, посмотрел ил. И увидел кое-что ещё круче. Что конкат вообще зло, так как + это синтаксический сахар, и иногда он оптимизурется в string.Intern (хотя я думаю про интернирование строк многие даже не в курсе) И у всего этого был один нюанс — под десктопом. Потом мы как-то сидели и болтали с кем-то из Unity, и он предложил скомпилировать под IOS) И там в IL результате внезапно была разница :) Хотя в целом компилятор шарпа умный, и сейчас ещё больше сахара напишет оптимальнее вас

2. Нюансы работы процессора

Разные процессоры под разными платформами в зависимости от поколения работают по разному. Вы скажете и что? Да дело в том, что ваш тест может быть написан так, что вам "неповезло" и вы получили скажем кешлайнсплит на каком-нить тайгер лейке, поэтому операция работает медленнее. А на m1 его не будет, так как там банально другой размер и организация кеша процессора :) Поэтому бывают иногда странные пики, которые потом возводят в ранг теории заговора, что "вот автопроперти в 30 раз медленнее, чем филды" :) И это довольно трудно учитывать

3. Нюансы окружения

Телеметрия винды, антивирусы, фоновые процессы и тому подобное. Всё это может запустится, занять время процессора, а вы это даже не узнаете. Поэтому замеров надо проводить много) И указывать их число, чтобы было понятно, что и как)

Автор в любом случае молодец, что проделал такую работу. И допустим факт про кеширование Camera.main в 2019.3 я думаю многие не знают. Проблема правда, когда такую инфу начинают на собеседованиях использовать не до конца разобравшись в вопросе :) Но я скажу так. Такую информацию можно слушать "по-приколу", иметь ввиду, но не "мы переписываем весь проект, ваш код говно, ты что дурак не кешировать?" :)

Базовое правило — не тормозит, не трогай. И писать лучше в стиле, где меньше лишнего кода. От того, что вы выиграете 100 нано секунд — ничего не изменится в программе. Оптимизировать нужно только тогда, когда тормозит. И только с профайлером. Есть некое базовое правило, так как вы не управляете сборкой мусора — не сорить в память, так как это непредсказуемые тормоза. А остальное тормоза по большей части предсказуемые :)
👍2