TGViewer
Channel Public Channel
Unity Architect: архитектура unity проектов

Unity Architect: архитектура unity проектов

@uniarchitect

Пишу о том, что нельзя нагуглить про архитектуру, разработку и пр.

Мой курс по архитектуре: https://course.uniarchitect.dev/y/9b8ec0c

Иногда выкладываю видео и веду стримы: youtube.com/@vangogih

По всем вопросам: @vangogih
Subscribers
5.23K
Photos
35
Videos
2
Links
99

Showing posts older than #175 · Back to latest

Older Posts 19 shown
Post #174 3.36K
MENUITEM

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

О чем речь:
— Открыть Persistent Data Path в проводнике
— Переключить сцену, чтобы не искать её в иерархии
— Удалить закешированные данные
— Переключить редактор из dev в prod или qa

И прочие мелочи, которые нужно часто вызывать в редакторе.
Обычно для этого создаётся скрипт с атрибутом [MenuItem("Tools/...")].

🔸Проблема

Почему-то этот полезный код очень любят разбрасывать по скриптам, папкам, сборкам.
Сторонние плагины туда же — Odin, DoTween и прочие имеют свои секции в Tools.

Поиск нужной кнопки начинает отнимать время.
Помножь на количество рабочих дней — получишь кучу времени потраченного на поиск.

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

Мелочь, но дико бесит 😵

🔸Решение

Всего 3 пункта:

1️⃣ Далем Editor asmdef в проекте: GenshinImpact.Editor

2️⃣ Все пути кладутся в 1 файл с константами, который лежит в корне:
public static class ToolConstants {
public const string Root = "Silverfox";
public static class Build {
public const string Prod = Root + "/Build/Prod";
}
}


3️⃣ При создании tool'а в качестве корня — имя проекта или компании: [MenuItem("Silverfox/Clean local data")]

Итого получаем в коде: [MenuItem(ToolConstants.Build.Prod)]

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

🔸Почему это работает

▫️ Не нужно держать в голове иерархию сборок. Достаточно найти строку Silverfox" — и ты сразу в файле со всеми tool'зами
▫️ Можно быстро прикинуть иерархию и понять как добавить или поправить tool. Особенно это полезно для новичков в проекте.
▫️ Быстрее чем спрашивать AI — переключение контекста и формулировка вопроса медленнее чем Ctrl+Shift+F в IDE

🔻 Простое соглашение — один файл, один корень — убирает целый класс раздражающих пауз в работе.

Это новая рубрика #решения@UniArchitect — короткие и простые решения, которые хотелось бы видеть чаще на проектах.
Они нигде не зафиксированы и каждый делает что-то подобное у себя. Хочется чтобы такие мелочи были под рукой.

Ставь 👍 если тебе по кайфу такая движуха!
Ты знаешь кому переслать эту статью 💪

#решения@UniArchitect
  • 👍 65
  • 💯 1
Post #173 4.22K
UNITEXT

TextMeshPro — это покупка 2017 года, которую Unity встроила и с тех пор поддерживала на плаву, исправляя баги.

Я не гуру нюансов отрисовки текста, но я никогда и не задумывался что TMP, по стандарту Unicode, не способен отобразить все многообразие символов правильно 😱

Я решил разобраться подробнее в различиях и фичах, чтобы понять в чем инновационность UniText.

🔸Эмодзи

Чтобы показать эмодзи в TMP, тебе нужно: создать текстурный атлас со спрайтами, импортировать его, разметить каждый спрайт, привязать к компоненту.

И всё равно ты получишь статичную картинку без поддержки Zero Width Joiner (семьи, флаги, тона кожи).

В UniText ты просто пишешь "Привет! 👋🏽" — и оно работает. Эмодзи берутся нативно с каждой платформы: Segoe на Windows, Apple Color Emoji на iOS, NotoColorEmoji на Android/Linux.

Мне смешно об этом писать, но теперь emoji просто есть и не нужно костылить fallback шрифт в новых версиях и свой атлас emoji в старых версиях TMP.

🔸RTL и смешанный текст

Арабский, иврит, урду, фарси — ни одно решение в Unity не реализует Bidirectional алгоритм по спецификации Unicode.

Костыль вроде RTLTMPro покрывает базовый кейс, но ломается на смешанном тексте — когда в одной строке арабский и английский.

Правильное отображение смешанного текста — это не просто "перевернуть строку".
В Unicode разработали для этого целую спецификацию UAX #9 с 861 тысячей тестов.

Каждый тест — конкретная комбинация символов разных направлений и ожидаемый порядок отображения.
Проходит все тесты — текст корректен в любой комбинации языков.

UniText проходит их все:
▫️ Bidirectional (направление текста)
▫️ Line Breaking (где можно переносить строку)
▫️ Grapheme Clusters (что считать одним "символом" — важно для эмодзи и составных букв)

TMP ничего из этого не проходит на 100% 🫠
Т.е. нет гарантий что чат в вашей игре будет правильно показывать что пользователь написал.

🔸Шрифты без боли


1️⃣ TMP растеризует глифы оффлайн в редакторе и сериализует атласы на диск.
Отсюда грязные файлы в git, конфликты при мёрже, раздутый билд.

UniText растеризует глифы в runtime — атласы не сериализуются, в проекте хранятся только байты шрифтов (UniTextFont.cs).
Никаких грязных файлов, никаких конфликтов.

Кто вдруг не понял:
В UniText не нужно постоянно отменять изменения в папке как Text Mesh Pro 🤯


2️⃣ В UniText один компонент рендерит текст на любом языке через стек шрифтов с fallback — первый шрифт основной, остальные подхватывают недостающие глифы (UniTextFontStack.cs).

3️⃣ А Font Subsetter позволяет вырезать из шрифта только нужные символы — полезно когда из 10МБ шрифта тебе нужны только символы валют.

И это я лишь малая часть отличий.

🔸Итого

🔻UniText это координально другой подход при работе с текстом, который на голову выше TMP.

Делаю ставку что это новый стандарт в Unity и скоро он будет на каждом проекте 🫡

Там сейчас 2 версии доступно:
1.0 — бесплатный и open-source. Всё что описано выше — доступно прямо сейчас.

2.0 — платная версия с, компрессией шрифтов, единым атласом с дефрагментацией, 3D-текстом и батчингом всего текста в 1 draw call 😍и полностью переработанной системой стилей (см. видео к посту).

🔸Рекомендация

Если у тебя проект с поддержкой японского, китайского, хинди, индонезийских или арабских локализаций — импортируй UniText и сравни размер билда.

Для больших проектов с десятком языков это может стать значительной победой.

Так что бегите скорее выпрашивать лицензию у компании для теста. Чисто изян способ реально улучшить метрики проекта 🛞

Мне посчастливилось знать лично разработчика этого плагина, поэтому пишите комментарии с вопросами и обязательно накиньте ⭐️ на GitHub ❤️‍🔥

📱 UniText Open Source
Документация
📱 Discord сообщество

Ставь 👍 если тебе заходит такого рода контент!
Ты знаешь кому переслать эту статью 💪

#будни@UniArchitect
  • 👍 71
  • 🔥 17
  • 🤨 5
  • 🤷‍♂ 1
Post #172 3.67K
ADR: ФИКСАЦИЯ АРХИТЕКТУРНЫХ РЕШЕНИЙ

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

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

Вот только один момент мы не учиваем: "А почему это сделано именно так и почему это никто не спешит исправить?".

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

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

🔸Проблема: устные договорённости

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

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

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

А как мы знаем, архитектура — это набор ключевых решений. Но решения без зафиксированного контекста — просто факты без объяснения.

🔸ADR: формат

В 2011 Michael Nygard предложил формат Architecture Decision Records (ADR).

Формат минимален:
▫️ Status — proposed, accepted, deprecated, superseded
▫️ Context — какая ситуация и ограничения привели к решению
▫️ Decision — что именно решили
▫️ Consequences — что из этого следует, включая негативные эффекты


🔹Ключевое: ADR фиксирует не "что мы сделали", а "почему мы так решили".

🔸Правила ведения

▫️Каждый документ включает только одно решение
▫️Информация из ADR при изменениях не удаляется — статус меняется на deprecated или superseded, создаётся новый ADR со ссылкой
▫️Файлы максимально атомарные и легковесные — пара параграфов
▫️Хранятся в системе контроля версий рядом с кодом, не в wiki

Для Unity-проекта: папка ADR в корне репозитория.
Пример формата из реального open-source проекта C4G — ADR прямо в корне репозитория.

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

🔸ADR и проектирование

ADR дополняет C4: уровни System/Container/Component показывают что и как устроено, ADR объясняет почему именно так.

Требования
определяют что система должна делать. ADR фиксирует как мы решили это реализовать и какие альтернативы отвергли.

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

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

Если кто-то придёт и скажет "давайте использовать нативные okhttp и alamofire" — а у тебя ADR:
Status: accepted.
Context: нужен кроссплатформенный HTTP на iOS/Android/WebGL.
Decision: используем BestHTTP.

Хочешь менять — сделай исследование, обоснуй, создай новый ADR, примите решение, внесите изменения.

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

Для примера можете посмотреть:
▫️Как структурированы предложения фичей для языка C#
▫️Простой шаблон ADR, что я упомянул в статье
▫️Как мы описываем ADR'ы на проекте, который создан на курсе

Ставь 👍 если тебе заходит такого рода контент!
Ты знаешь кому переслать эту статью 💪

#проектирование@UniArchitect
  • 👍 41
  • 🔥 3
Post #171 3.91K
ПРОЕКТИРОВАНИЕ: КОМПОНЕНТЫ

Слово "компонент" — одно из самых перегруженных в разработке. В Unity это MonoBehaviour, в ECS — struct с данными, в пакетном менеджере — package.
В модели C4 — совершенно другое.

Много раз видел как разработчики рисуют схемы, добавляя на одну диаграмму и крупные подсистемы (UI, Networking, Analytics), и конкретные классы внутри них.
Всё на одном листе, без разделения по масштабу.
Результат — схема, которую понимает только автор.

И вот в чём причина. Между уровнем контейнеров ("что мы деплоим") и уровнем кода ("какие классы пишем") — пропасть.
Контейнеры слишком крупные чтобы по ним начинать имплементацию. Классы слишком мелкие чтобы по ним планировать.

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

🔸Что такое компонент в C4

Компонент в модели C4 — это группа связанной функциональности за чётким интерфейсом (API, модель, фасад). Не один класс, не файл — а логическая единица (чаще папка), выделенная из кода по ответственности.

Компонент:
▫️ Живёт внутри контейнера
▫️ НЕ деплоится отдельно — деплоится контейнер
▫️ Все компоненты одного контейнера выполняются в одном процессе

В Unity-проекте ближайшая аналогия — внутренняя структура asmdef: из каких подсистем она состоит.
Но маппинг не 1:1 — один компонент может быть размазан по нескольким asmdef, а одна asmdef может содержать несколько компонентов.

❗️ Уровень компонентов и Unity-компоненты (MonoBehaviour/IComponentData) — абсолютно разные, не связанные понятия.

🔸Пример: Unity-клиент

В статье про контейнеры мы установили — Unity-клиент это монолит, 1 деплоемый unit. Но внутри этого монолита есть структура.

В типичном проекте есть инфраструктурный слой, который очевиден:
— UI, Networking, Assets, Analytics, Save

Но ценность уровня компонентов проявляется в декомпозиции игровой логики. Именно тут начинаются вопросы:
▫️ Battle System — боевая механика, расчёт урона, управление раундами
▫️ Meta Game — прогрессия, апгрейды, разблокировки
▫️ Social — кланы, чат, друзья, лидерборды
▫️ Economy — валюты, магазин, инвентарь, покупки

Каждый — группа систем и их фасадов (моделей), которые предоставляют API внешним системам.
На уровне компонентов нам не важно что внутри. Важно что он делает и с чем связан.

🔸Когда это нужно, а когда нет

Сайт C4 прямо говорит:
component diagram — not recommended by default.

Делай только если приносит пользу.

Когда я проектировал чат в Nexters, лид инфраструктурного направления требовал проектирования уровня контейнеров — какие сервисы, как деплоятся, как связаны. Но когда я запроектировал и уровень компонентов, он сказал: "это излишне".

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

🔹 Уровень контейнеров — для инфраструктурщиков: как сервис встраивается в инфраструктуру
🔹 Уровень компонентов — для программистов: как разбить систему на части и распределить работу

🔸Как не свалиться в код

Если на схеме появляются конкретные классы — ты уже на уровне кода.

Компонент описывается через ответственность, а не реализацию:
— ✅ "Economy — управление валютами, покупками и инвентарём"
— ❌ "WalletService вызывает TransactionValidator, который использует CurrencyConverter"

Смешивая уровни, ты получаешь схему, которую понимаешь только ты, + ускоряешь устаревание документации.
Уровень кода меняется гораздо чаще, чем уровень компонентов.

🔻 Уровень компонентов существует чтобы закрыть разрыв между "что мы деплоим" и "какие классы пишем".
Без него — либо проектируешь слишком крупно и схема бесполезна для имплементации, либо слишком мелко и схема нечитаема.

Следующая статья серии — уровень кода. Тот самый, который стоит генерировать, а не проектировать ручками 😅

Ставь 👍 если тебе заходит такого рода контент!
Ты знаешь кому переслать эту статью 💪

#проектирование@UniArchitect
  • 👍 48
  • 🔥 10
Post #170 4.25K
CORECLR АНОНС АЛЬФЫ

Пару дней назад на GDC Unity анонсировала Alpha релиз CoreCLR в Unity.

Странно, но почему-то новость не встретила большого хайпа и бурного обсуждения.
Наверное, потому что это, пока, все еще обещание, а не фактический релиз.
Более того, новость Unity пока опубликовали в виде короткого shorts на youtube.

Для тех, кто вдруг пропустил, я написал 3 подробных поста сравнения основных отличий и преимуществ, что нам даст CoreCLR:
▫️CoreCLR в Unity — это круто
▫️CoreCLR vs Mono
▫️CoreCLR vs IL2CPP

🔸Что мы узнали нового:

1️⃣ Alpha релиз будет в версии 6.8 позже в этом году
Ну, как говорится: "Могу только поставить 🕯 и верить, что в этот раз версия и сроки не будут сдвинуты".

А если серьезно, то назначение конкретного номера версии — это уже коммитмент по срокам.
🔻Мой прогноз:
6.8 точно не LTS, а значит, это tech release. 6.4а и 6.5а (текущие tech release) были выпущены в Октябре-Декабре.
Ожидаю, что 6.8a появится с Сентября по Декабрь 2026.

2️⃣ У нас будет .NET 10 и C# 14
И тут сюрприз — ожидал максимум .NET 8, а получили сразу десятку.

Поддержка именно последней версии .NET и C# говорит о том, что маловероятно это будет fork .NET с фиксами, как это было с Mono.

Что, безусловно, радует — возможно, будем регулярно получать свежие версии .NET в Unity.

3️⃣ Прощай Domain Reload и Mono
Ну, тут лишь подтверждение моего прогноза из поста CoreCLR vs Mono:
Время Domain Reload снизится минимум на 75%.
В моём примере — с 12 секунд до 3. Останутся только вызовы Awake/Destroy и десериализация состояния сцен.

Технически, именно Domain Reload и правда уйдет в небытие как термин. Т.к. мы будем выгружать не весь домен, а лишь перекомпилированные assembly.

Потому просто жду переименования Domain в Assembly Reload (или что-то около).
Это и правда уберет примерно 75% времени, но вот избавиться от вызовов Awake/Destroy/InitializeOnLoad, а также полного сброса состояния сцены и редактора, мне кажется, что не получится.

Так что прогноз все еще валидный, ждем релиза и замеров 😊

4️⃣ Полный переход на csproj и msbuild
Тут, если не знать деталей, как компилируется проект, можно сразу задать вопрос: "И что нам это дает?".

Сейчас компиляция проекта выглядит примерно так:
Изменение в скрипте
|- Изменения видит редактор
|- Запуск рекомпиляции
|- bee_backend (
|— Чтение DAG файла (ориентированный ацикличного граф, который построила Tundra)
|— Расчёт хэшей
|— Если хэш другой
|— Вызываем msbuild на каждой ноде (по факту asmdef)
|— Domain Reload

И переход на csproj и msbuild позволит полностью уйти от bee_backend и переложить всю обязанность за рекомпиляцию на msbuild.

И это просто пушка-бомба, описать сколько всего изменится, поста не хватит, но вот несколько самых важных пунктов:

🔸 Раньше, новые фичи компилятора приходилось согласовывать с bee_backend.
Т.е. нельзя было просто включить тот же SourceGenerator. Нужно было жестко шаманить (там гайд на 14 пунктов так-то).

С CoreCLR, просто поставил атрибут и все заработало сразу. И ладно мы этому радуемся, а как рад этому весь тех. отдел Unity, которому больше не нужно придумывать, как вкорячить новую фичу .NET в движок 😇

🔸 Управление зависимостями переедет в csproj. Никаких больше NuGet for Unity и asmdef.
сsproj по объему функционала напрочь разрывает все то, что есть в asmdef.
Могу здесь ошибиться с полным избавлением от asmdef, сам ассет, скорее всего, останется для обратной совместимости, но наверняка будет сильно изменен.

🔸 Можно будет скомпилировать проект, не запуская unity.
Прикиньте, можно будет editor тесты или код без unity зависимостей взять и запустить без самой Unity.
Там целое поле для оптимизаций CI пайплайна открывается 😊

Про остальные пункты напишу в комментах, т.к. в пост тупо все не влезет.

Присоединяйтесь к тусовке и давайте вместе подумаем что еще изменится в Unity благодаря этому обновлению 👨‍💻

Ты знаешь, кому переслать этот пост 🫡
Ставь 👍 если уже начал обратный отсчет дней до релиза 6.8a 😅

#проект_в_разработке@UniArchitect
YouTube Unity CoreCLR Roadmap Get ready for a Unity 6.8 alpha coming later this year, as we prepa...
  • 🔥 65
  • 👍 19
  • 🐳 2
Post #166 4.28K
ПРОЕКТИРОВАНИЕ: ТРЕБОВАНИЯ

В прошлой статье мы разобрали исследование, где 43 из 68 работ указали на размытые требования как корень неверной оценки сроков.
И пообещал разобрать — что конкретно должно быть в документе, чтобы не влетать в бесконечные доработки.

Давайте на чистоту. Мы не так часто вносим правки в геймдизайн документы.
Получил GDD — сел делать. А потом неделя за неделей всплывают кейсы, которые никто не описал. Вот оно, расширение сроков.

🔸Функциональные требования

По IEEE 1471-2000 (это то самое определение архитектуры ПО по стандарту), у стейкхолдеров есть viewpoint — видение того, как система должна работать. На практике этот viewpoint и есть GDD.

Уже из него программисты должны формировать architectural description (AD) — техническую документацию по сути. В геймдеве AD почти никто не делает, потому все обычно прописывается в GDD (viewpoint).

Хороший GDD содержит:
▫️Функциональное описание механик
▫️Визуальное видение: мокапы, скетчи, референсы
▫️Краевые случаи
▫️Пользовательские истории

🔸User Stories — лучший формат

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

Почему это работает:
▪️Иерархическая структура "если … то …" один в один ложится в код
▪️QA берет документ и сразу получает список кейсов для проверки
▪️Легко инвертировать: "а что если НЕ?" — и ты находишь пропущенные краевые случаи

Они делятся на два типа:
▫️Happy path — основной поток без ошибок
▫️Alternative path — что происходит когда что-то пошло не так

Пример:
— Happy: если я нажму кнопку "Купить", я увижу подтверждение покупки
— Alt 1: если у меня недостаточно валюты, я увижу предложение пополнить баланс
— Alt 2: если во время покупки пропал интернет, я увижу сообщение об ошибке и мой баланс не изменится


Happy path прямолинеен и понятен. А вот устойчивые системы отличаются проработкой alternative path.
Именно на них тратится 80% усилий и именно они формируют стабильность приложения.

🔸Нефункциональные требования

Вот тут начинается самое интересное. Геймдизайнер пишет: "два игрока стреляют в мишень по очереди". Задача на 5 дней, да?

А теперь в комнату заходят нефункциональные требования:
▫️Соединение двух игроков → сервер
▫️Авторизация → база данных
▫️Синхронизация данных → протокол обмена
▫️Потеря соединения → механизм переподключения
▫️Таймаут ожидания → логика прерывания сессии

Одна строчка в GDD превратилась в инфраструктурную задачу. И это не исключение — это норма.

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

Всё "очевидное", что никто не удосуживается описать — и что потом сдвигает сроки.

🔸Как находить пропущенное

Большая ошибка — не участвовать в уточнении документов. Это часть профессиональной компетенции разработчика.

Два способа проверять документы на полноту:

1️⃣ Строишь execution path — проходишь каждый шаг user story и пытаешься сломать его. "А что если НЕ нажал?" "А что если сервер не ответил?" "А что если два события одновременно?" Каждый else, который не описан — это пропущенное требование.

2️⃣ Скармливаешь документ GPT и просишь найти проблемы. Серьезно. Он находит пропущенные краевые случаи, нестыковки и неоднозначности быстрее, чем ты прочитаешь документ второй раз.

Критерий простой:
Если в процессе чтения документа или написания кода тебе нужно что-то додумывать — значит этот момент не был учтен в требованиях.

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

И только так, лично у меня, получается без всяких НО планировать и сдавать задачи в срок.

Ставь 👍 если тебе заходит такого рода контент!
Ты знаешь кому переслать эту статью 💪

#проектирование@UniArchitect
  • 👍 50
  • 🔥 15
Post #164 4.29K
ASSET BUNDLES ПО КИРПИЧИКАМ

С Октября 2024 по Июль 2025 я вёл курс по архитектуре. 1-2 раза в неделю, по полтора-два часа. 40 человек. Перед этим полгода собирал и прорабатывал материал.

Во время ведения курса я пообещал ребятам дополнительное занятие — глубокое погружение во внутреннее устройство Unity.
Не "как пользоваться API", а как оно работает изнутри, на уровне исходников.

Первым таким занятием стала система компиляции: Bee, Tundra, Domain Reload. Где не просто разобрал теорию — написал программу, которая компилирует скрипты без самой Unity 🛞

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

Меня очень удивило и порадовало что 10 человек из группы попросили провести ещё одно такое занятие.
Тему выбрали сами: Asset Bundles.

Я подумал:
Вдруг кому-то ещё в блоге будет интересно разобраться в том, как на самом деле устроен этот механизм?

И решил что хочу попробовать такой формат активности в блоге 😊

🔸Что будем разбирать

Никакой воды и общей информации из документации.
Мы полезем в исходники и по кирпичикам разберём:

▫️ Формат архива UnityFS — побайтово: заголовок, таблица блоков, директория файлов
▫️ Сериализация и TypeTree — как Unity сериализует объекты внутри бандла, что такое PPtr
▫️ Компрессия — LZ4 vs LZMA на уровне кода: почему LZ4 даёт random access, а LZMA нет
▫️ Пайплайн загрузки — полный путь от вызова LoadFromFile до готового AssetBundle
▫️ Пайплайн выгрузки — batch-удаление, освобождение хэндлов, очистка хранилища
▫️ Платформозависимость — почему бандл для Android не загрузится на iOS
▫️ Загрузка ассетов — как LoadAsset строит граф зависимостей между бандлами
▫️ Патчинг и рекомпрессия — hot swap бандлов без потери C# ссылок

🔸Формат

— 28 февраля, 14:00 МСК
— Онлайн в Zoom
— После занятия в закрытую Telegram группу будут выложены: запись, текстовые материалы и исходный код программ-примеров
— Доступ к группе и материалам остаётся навсегда
— Вопросы можно задать в любой момент в приватном чате

🔻Это не пересказ документации. Это разбор того, что происходит под капотом — на уровне, который не найти в гайдах и туториалах.

Тут была ссылка на покупку 😬

Занятие прошло по расписанию без накладок.
Отзыв одного из участников, Lead >10 лет опыта:
Самый большой вау-эффект был именно от осознания того, что работа с любыми ассетами в Unity устроена похожим образом и AssetBundle не исключение а дополнение для этого. Плюс само по себе разбор формата файлов раскрывает уйму возможностей: можно писать свои патчеры или шифраторы/дешифраторы.


Думаю что в будущем часть материала появится в публичном доступе, следите за обновлениями 🫡

#курс@UniArchitect
  • 🔥 17
  • 👍 4
Post #163 3.98K
МАШИНА СОСТОЯНИЙ - АДище

Машина состояний — один из самых интуитивно понятных подходов. Нарисовал квадратики, провёл стрелочки, описал условия переходов — готово.

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

Ты не сможешь продумать все возможные события и условия переходов. Рано или поздно это приведёт к зависанию в одном состоянии машины.

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


Чуть более простым языком эту проблему можно описать так:
Событие, поступившее конечному автомату в некотором контексте, может не вызвать никакого действия, поскольку автомат не в состоянии однозначно определить, какое именно действие должно быть выполнено, исходя из полученного входного сигнала и текущего состояния машины.
🔸Пример 1: Loading

Сцена Loading — инициализация, подключение к серверу, скачивание конфигов.
Следующее состояние — Meta, главное меню.
Переход Loading → Meta срабатывает по условию: «все конфиги загружены и соединение активно».

Пользователь во время скачивания свернул приложение чтобы прочитать новый пост по архитектуре 😎 и вернулся через 10 минут. Соединение отвалилось по таймауту, часть конфигов скачалась, часть — нет.

Приложение получает OnApplicationPause(false) — «пользователь вернулся». Машина всё ещё в Loading. Но конфиги не все, а соединение мертво.
Перехода «переподключиться» не предусмотрено, потому что автор не заложил комбинацию «Loading + потеря соединения + частичная загрузка + выход из паузы».

Событие пришло, а ни один переход не сработал — игра зависла в Loading навсегда.

🔹Пример 2: Пауза

Цепочка уровней и игровой цикл: открыл уровень → бой → противники убиты → сбор наград → заход в триггер следующего уровня → повторить. Очень легко описать в виде машины.
Помимо этих состояний есть ещё Paused — оно активируется кнопкой окна настроек.

На стадии «заход в триггер следующего уровня» пользователь делает frame-perfext noscope360 в пиксель кнопки настроек и открывает окно, когда не должен 🤣

Машина переходит в Paused, но перехода из Paused обратно в «триггер следующего уровня» не существует — он просто не был прописан.
Окно закрывается, а игра остаётся в Paused навсегда.

🔸И вот ключевой момент

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

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

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

🔻Каждое новое состояние или событие мультиплицирует количество переходов, которые нужно определить. N состояний и M событий — это N×M переходов, и если хоть один не определён, есть риск перехода в невалидное состояние.

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

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

🔻Так что пожалуйста, не надо. Вам не нужна машина состояний для "контроля" состояния приложения и окон 🫠

Вредно как со стороны сложности проекта, так и со стороны нашего ментального здоровья.
Развивает параною "а я точно исправил проблему или опять какой-то кейс не покрыл" 😵‍💫

Делитесь своими историями исправления сложных багов в комментах, уверен у каждого есть пачка таких 🫡

Ставь 👍 если тебе заходит такого рода контент!
Ты знаешь кому переслать эту статью 💪

#проект_в_разработке@UniArchitect
#проект_с_нуля@UniArchitect
  • 👍 14
  • 🤨 9
  • 🤔 1
Post #162 4.42K
ПРИЧИНА ПРОВАЛА ПРОЕКТОВ

В Magic Battle Arena мы с партнером привлекли pre-seed раунд с runway на 1 год 2 месяца.
Я уже рассказывал об этом: раз, два, три

Думали — хватит. Рассчитывали 8 месяцев на MVP, 4 месяца на итерации.
По факту 4 месяцев хватило только начать улучшать метрики. Нужно было runway минимум в 2 раза больше.
Неверная оценка сроков стала краеугольной ошибкой, которая привела к закрытию компании.

А вот смотрите что говорит наука.

🔸Исследование 2019 года: качество кода не при чем

В 2019 году исследователи проанализировали 2171 публикацию с 1990 по 2017 год по теме провала ПО. Из них отобрали 68 наиболее релевантных и тщательно изучили.

Задача: выявить и ранжировать факторы провала IT проектов.

Как думаете, насколько техническое качество кода оказалось важным? 🤓
Insignificant — ничтожно малым. Из 13 выявленных факторов technology illiteracy попала в самый низ.

А вот главный фактор:
▫️ Wrong estimation of time and cost — неверная оценка времени и стоимости
▫️ 43 из 68 исследований указали на это как основную причину провала

🔸Другое исследование: откуда берется неверная оценка?

Исследователи из Aalto University в 2014 году провели анализ корневых причин 4 случаев провала в продуктовых компаниях. Для каждого кейса строили диаграмму причинно-следственных связей — от 130 до 185 причин.

Три основные связи повторялись в 3 из 4 кейсов:

▫️ Weak Task Backlog — расплывчатые требования, неверные приоритеты
▫️ Lack of Cooperation — между отделами теряется информация, нужная для реализации и тестирования
▫️ Lack of Software Testing Resources — менеджмент недовыделяет ресурсы на тестирование

И две из трех цепочек как раз проходят через Sales & Requirements.
▫️Расплывчатые спецификации → слабый backlog → неверные приоритеты.
▫️Недостаток коммуникации → потеря информации → разработчики и тестировщики не понимают что делать.

Требования — точка, где теряется критическая информация.

🔹На Combat Quest я это ощутил на себе.

Настраивал процессы с нуля. В GD-документах постоянно пропускали краевые случаи — альтернативные сценарии использования, граничные случаи, обработку ошибок.
Результат: расширение сроков, переработки, выгорание команды 😵

Код был нормальный. Проблема была в том, что мы не прогоняли сценарии использования.
▪️Тут окно нужно добавить — плюс 10 дней.
▪️Там забыли что игра делает мягкую перезагрузку при исключении.
▪️Не учли что игрок в метро и запрос обрабатывается с задержкой.
▪️Где-то просто не прописали полный список фичей и срочно добивали потом.

Именно 👆 поток нескончаемых доработок, на моем опыте, в итоге постоянно двигал deadline'ы.

🔸Сначала требования, потом диаграммы

В комментариях к статьям про проектирование правильно подмечали — первыми идут требования.
Исследования это подтверждают — 43 из 68 указали на размытые требования как корень неверной оценки.

Посмотрите на картинку из поста с определением архитектуры — именно видение заказчиков (= требования) формирует описание архитектуры и финальную систему.

Модель C4 — система и контейнеры — помогает зафиксировать требования визуально.
Показать заинтересованным сторонам что будет построено, какие элементы задействованы, как они связаны.
Но диаграмма без требований — просто картинка.

🔻 Потому оч важно выработать привычку:
При чтении документов прокручивать варианты, когда что-то идет не по плану. Проговаривать их с командой и закладывать буфер при оценке.
Ну или прогонять сценарии через GPT — ТОП вариант 😅

А о том, что должно быть в документе с требованиями — обсудим в следующей статье серии.

Ставь 👍 если тебе заходит такого рода контент!

#проектирование@UniArchitect
  • 👍 70
  • 🔥 15
  • 💯 2
  • 🤔 1
Post #160 3.7K
CORECLR VS IL2CPP

Это последняя статья из цикла: "CoreCLR - это круто", где я стараюсь рассказать про основные, важные изменения, которые CoreCLR может превнести.
Предыдущие статьи: раз, два.

На этот раз поговорим про различия в runtime'ах, которые непосредственно исполняются на пользовательских девайсах (а не в редакторе, как в прошлых статьях).

🔸VTable

Когда вызываешь виртуальный метод, runtime должен понять какой именно код исполнить.
У базового класса и наследника методы разные, но вызов 📞 выглядит одинаково.

VTable — это массив указателей на методы. Каждый тип хранит свою таблицу.
Вызов виртуального метода = взять указатель из таблицы по номеру слота и сделать jmp на значение указателя в слоте.

🔸Где IL2CPP добавляет работы

В CoreCLR vtable — просто массив указателей на код. 8 байт на слот.

В IL2CPP каждый слот содержит ДВА указателя: на код и на метаданные. 16 байт.
Зачем? IL2CPP — это AOT. Нет JIT, который достроил бы информацию в runtime. Всё предсгенерировано заранее.

Но главное размер. CoreCLR разделяет информацию о типе на "горячую" (MethodTable — только для исполнения) и "холодную" (EEClass: reflection, interop).
При виртуальном вызове CPU загружает в кэш только MethodTable.

IL2CPP держит всё в одной Il2CppClass — 200+ байт.
При частых вызовах методов разных типов процессор постоянно выгружает одни данные из кэша и загружает другие.

Отсюда и сложно писать производительный код без Burst: ты теряешь контроль над тем, что по факту у тебя исполняется на устройстве 😬

🔸Interface Dispatch — тут разница огромная

Интерфейсы сложнее классов. Один тип может реализовать много интерфейсов, и runtime должен найти нужную реализацию по указателю на интерфейс.

IL2CPP хранит массив interfaceOffsets — пары "указатель на интерфейс + смещение в vtable".
При каждом вызове метода интерфейса il2cpp идёт циклом по этому массиву, сравнивая указатели:
if (interfaceOffsets[i].interfaceType == declaringInterface)

Линейный поиск короче.
Можешь посмотреть сам, файл: ClassInlines.h в исходниках il2cpp.

Т.е. если тип реализует 5 интерфейсов — в среднем 2-3 сравнения указателей. 20 интерфейсов — ~10 сравнений.
С одной стороны копеечки, а с другой часто от других разрабов слышу что это всегда jmp на указатель с кодом 🤔

CoreCLR же использует Virtual Stub Dispatch.
При первом вызове генерируется stub — кусок машинного кода, который запоминает результат поиска.
Все последующие вызовы — один jmp без цикла. O(1).

Т.е. IL2CPP платит за каждый interface-вызов, CoreCLR — только за первый.

🔸GC

IL2CPP сидит на Boehm GC — консервативный сборщик без поколений и без уплотнения памяти. Объекты никогда не перемещаются. При долгих сессиях память фрагментируется, для аллокации идет поиск "дырок" в free list.

И тут можно долго говорить о различиях, но самое крутое — это наличие Background GC в CoreCLR.
Если эту штуку смогут хотябы частично адаптировать под unity будет пушка бомба.
Меньше заботы о spike'ах при работе GC это всегда приятно 😊

И вот тут прикольно:
Большая часть "рекомендаций" с оптимизациями и уменьшению аллокаций с переходом CoreCLR могут кардинально измениться и начнется снова рассвет полезных постов с лайфхаками в соц. сетях 😬

🔻 Для тех кто задавался вопросом: "Чего так все с этим CoreCLR бегают?", мой короткий ответ:
Та прост эта штука может оч сильно изменить подход к тому как мы привыкли писать код под unity.

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

Ставь 😁 если задушил жестко и надо проще или 👍 если все норм и тебе заходит такой контент!

#unite2025@UniArchitect
#проект_в_разработке@UniArchitect
  • 👍 101
  • 🔥 6
  • 😁 3
Post #159 4.29K
ПРОЕКТИРОВАНИЕ: КОНТЕЙНЕРЫ

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

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

В прошлой статье мы разобрали первый уровень модели C4 — System Context.
Он общий почти для всех игр на Unity, достаточно абстрактный и содержит мало конкретики.

Сегодня поговорим про второй уровень — контейнеры.

🔸Что такое контейнер

Контейнер в модели C4 (никак не связано с Docker!) — это приложение или хранилище данных. То, что должно быть запущено для работы всей программной системы.

Ключевой критерий: контейнер — это независимо деплоемая единица.

Примеры контейнеров:
▫️ Серверное приложение — http или любой другой сервер с логикой системы
▫️ Клиентское web-приложение — админка для управления данными пользователей
▫️ Мобильное приложение — бинарник, который пользователь скачивает на телефон
▫️ База данных — SQL или NoSQL решение для хранения данных игроков

Т.е. после того как у тебя готов общий уровень системы, ты определяешься какие элементы будут публиковаться и деплоиться независимо друг от друга.
Берёшь каждый элемент системы и разбиваешь его на отдельные деплоемые части.

🔸Пример: сервер для маленького проекта

Вот как бы я принимал решение о том, как сделать небольшой игровой сервер (< 100k скачиваний и 1k DAU).

Прикинем нагрузку. RPS на таких объёмах будет достаточно низкий:

1000 [игроков] / 24 [ч] / 60 [мин] / 60 [сек] ≈ 0.01 req/sec


Одного экземпляра http сервера на любой технологии будет более чем достаточно.
Значит всё серверное приложение — это 1 docker image, который можно опубликовать в Yandex/Google/Amazon Compute Cloud.

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

🔸Практические рекомендации

🔹 На крупных проектах может быть огромное количество элементов. Нет смысла упарываться в детализацию всех контейнеров всех элементов системы. Указывай только то, что нужно конкретному проектируемому элементу. Зависимости вне твоей зоны ответственности уточнять не нужно.

Пример из Hero Wars: для чата мы используем MQTT сервис, на топики которого подписывается клиент чтобы получать новые сообщения. Когда я проектировал чат, я не уточнял из чего состоит MQTT сервис и что он использует внутри — это избыточно и вне моей зоны ответственности.

🔹 На этом этапе полезно прописывать технологии, если они важны для проектируемого сервиса.

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

🔹 Unity-клиент на этом уровне детально не проектируется.

Любое Unity приложение — это монолит и всего 1 деплоемый unit.
Максимум что можно указать на схеме — платформы куда деплоимся. Но в большинстве случаев это избыточно.

🔻Проектирование можно и нужно начинать с двух простых шагов: сначала система и её ключевые элементы, затем уточнение каждого элемента деплоемыми unit'ами и технологиями.

Так ты получаешь не просто каркас, а полноценное верхнеуровневое понимание функционирования всего приложения.

Это вторая статья серии про проектирование. Дальше: компоненты и код.

Ставь 👍 если тебе заходит такого рода контент!
Ты знаешь кому переслать эту статью 💪

#проектирование@UniArchitect
  • 👍 46
  • 🔥 22
Post #157 4.91K
Mono vs CoreCLR

Последние несколько лет я много писал серверного кода на dotnet, и меня постоянно радовала скорость итерации.
Делаешь изменение — почти моментально получаешь отклик. В Unity это всегда боль.

Я постоянно стараюсь работать так, чтобы как можно реже триггерить Domain Reload.
Эта штука на каждое, даже мелкое изменение отнимает десятки секунд.
Если взять обычный день и просто посчитать время на ожидание — легко набегут десятки минут.

🔸Почему так происходит?

Редактор Unity на всех платформах работает на Mono — старом кроссплатформенном runtime. В его основе лежит JIT-компиляция.

Когда вызывается твой метод первый раз, туда прописан вызов JIT-компилятора.
Он берёт IL-код метода, конвертирует в Mono IR (внутреннее представление Mono), оптимизирует, и только после этого генерирует инструкции для конкретного процессора.

Казалось бы, при чём тут мы? А при том, что Mono JIT — операция не бесплатная. И в редакторе она обходится очень дорого.

🔸Domain Reload

Его порядок работы примерно такой:

1️⃣ Находим все MonoBehaviour и вызываем OnDisable/OnDestroy
2⃣ Выгружаем все *.dll движка и наши
3⃣ Освобождаем GC Handles и выгружаем Domain
4⃣ Создаём новый Domain и загружаем все *.dll движка
5⃣ Загружаем все *.dll игрока
6⃣ Запускаем скрипты с [InitializeOnLoad]
7⃣ На пересозданных MonoBehaviour вызываем Awake/OnEnable

На моём проекте Magic Battle Arena (~100к строк кода, 149 сборок) эти 7 пунктов занимают 12 секунд.
Угадайте какая операция самая долгая?

Mono JIT — примерно 5.5 секунд в сумме.

Это происходит потому, что мы вынуждены полностью выгрузить ВСЕ *.dll (для которых методы уже скомпилированы) и перекомпилировать их заново.

🔸Почему это нельзя исправить в Mono

Проблема фундаментальная. В Mono нет механизма hot swap для сборок. Нельзя сказать "выгрузи только эту dll и загрузи новую версию".
Только полная перезагрузка домена.

CoreCLR решает это через AssemblyLoadContext, см. прошлый пост

🔸RyuJIT vs Mono JIT

Но даже если Unity не реализует hot reload, сам JIT-компилятор CoreCLR (RyuJIT) работает иначе.

Mono JIT — однопроходный. Скомпилировал метод один раз — живи с этим. Хочешь лучше? Используй AOT.

RyuJIT поддерживает Tiered Compilation:
🔹Tier 0: быстрая компиляция без оптимизаций (для быстрого старта)
🔹Tier 1: метод был вызван более 30 раз и более? — Оптимизируем его

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

Но выиграем мы от смены JIT компилятора, я уверен не так много, как c перехода с Domain Reload на Code Reload.

🔻Мой прогноз:
Время Domain Reload снизится минимум на 75%.
В моём примере — с 12 секунд до 3. Останутся только вызовы Awake/Destroy и десериализация состояния сцен.

Проверим в 2025 2026 или 2027 году 🤣

Теперь ты знаешь что загадать на Новый Год 😊

Ставь 👍 если тебе заходит такого рода контент!
Ты знаешь кому переслать эту статью 💪

#unite2025@UniArchitect
#проект_в_разработке@UniArchitect
  • 👍 86
  • 🔥 8
  • 💯 2
Post #156 5.34K
CoreCLR в Unity - это круто🫡

Ты написал программу на C#, скомпилировал, получил .exe. Запускаешь — а Windows говорит "requires .NET Runtime". Почему?

Потому что C# компилируется не в машинный код, а в IL.
Windows не умеет его исполнять напрямую.
Нужен "движок исполнения" — runtime, который ты устанавливаешь отдельно (или он идёт bundled с приложением).

Runtime берёт IL и превращает в работающую программу.
Он определяет как каждый объект размещён в памяти, когда эта память освобождается, как вызываются виртуальные методы, как работают generics.

🔸Ключевые компоненты

▫️ Type System — хранит информацию о типах в памяти. Layout объекта: сначала Object Header (индекс SyncBlock для lock/hash), затем указатель на MethodTable.

Пример:
obj is IMyInterface. Runtime берёт MethodTable объекта (первое поле после header), смотрит в Interface Map — массив интерфейсов которые тип реализует.
Если интерфейс в списке — true. Для классов ещё проще: проход по цепочке Parent MethodTable.
Всё это O(1) или O(глубина наследования).

▫️ Virtual Machine (Execution Engine) — сердце runtime. Управляет потоками, загрузкой типов, виртуальными вызовами, координирует все подсистемы

▫️ JIT Compiler — компилирует IL в машинный код

▫️ Garbage Collector — управляет памятью, решает когда освобождать объекты

▫️ Interop — мост между managed и native кодом

🔸Почему это важно для Unity. Domain Reload.

Меняешь скрипт — Unity перезагружает весь managed домен. Выгружает ВСЕ сборки, пересоздаёт ВСЕ типы. На большом проекте это десятки секунд после каждого изменения.

CoreCLR предоставляет AssemblyLoadContext (ALC) — механизм изоляции сборок. Как это работает:

🔹Default ALC загружает framework и core assemblies — они живут всё время
🔹Custom ALC может загружать пользовательские сборки изолированно
🔹Collectible ALC позволяет выгружать сборки когда они больше не нужны

Т.е. вместо "выгрузить всё и загрузить заново" можно:
Cоздать новый ALC → загрузить изменённую сборку → переключить ссылки → выгрузить старый ALC. Framework, Unity assemblies, неизменённые скрипты остаются на месте.


🔻 Вот и 1 пункт почему переход на CoreCLR это круто - время Domain Reload может снизится в десятки или сотни раз, что == увеличению скорости итерации 😎

Дальше — как устроены Mono, IL2CPP и CoreCLR изнутри.

Ставь 👍 если тебе заходит такого рода контент!
Ты знаешь кому переслать эту статью 💪

#unite2025@UniArchitect
#проект_в_разработке@UniArchitect
  • 👍 198
  • 🔥 9
  • 💩 2
Post #154 5.76K
Интервью:
Архитектура Open Source проектов


Второе интервью, которое я успел записать на Unite 2025.

На этот раз пообщался с Dzmitry Bazyleu — разработчик плагина UniState 200+⭐️ на GitHub.

Я постарался задавать вопросы, которые редко звучат в инфо пространстве, но которыми начинаешь задаваться когда ведешь разработку своего Open Source проекта:

🔸Как стартануть и не забросить open source проект?

🔸Какие архитектуреные решения нужно принять при старте open source проекта?

👇👇👇
Ссылка на видео
👆👆👆

У меня так же есть пара прикольных проектов в Open Source, где есть все элементы, которые мы обсудили с Димой:

🔸FastMigrations.Json.Net - плагин для миграции json файлов
🔸Unity Empty Project Template - шаблон пустого unity проекта

Ставь 👍 если тебе по кайфу такая движуха

#unite2025
#интервью@UniArchitect
YouTube Dzmitry Bazyleu: Архитектура Open Source Проектов Dzmitry Bazyleu - разработчик плагина UniState, который имеет более 200⭐️ на GitHub. Подписывайся на мой блог в Telegram: https://t.me/+-kA-r9nWBvI2NTBi Второе интервью, которое я успел снять на #Unite2025. На этот раз поговорили о том как создать, сколько…
  • 👍 34
  • 🔥 10
  • 💯 4
  • 💩 1
Post #153 5.75K
Интервью:
Клиентская архитектура корпораций


На unite 2025 я времени зря не терял и успел записать несколько интервью с разными интересными людьми.

В первом интервью я общался с Ярославом Шабанцом — клиентский архитектор в компании Playtika.
Именно под его руководством получилось "уговорить" Unity добавить в движок поддержку HTTP/2 для UnityWebRequest 😈

👇👇👇
Ссылка на видео
👆👆👆

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

Может показаться что мы заранее договорились о том, что и как мы будем отвечать, но еще задолго до интервью, на некоторые темы затронутые темы я писал посты:
🔸 СТРУКТУРА ПРОЕКТА
🔸 СТРУКТУРА СБОРОК
🔸 (А|а)рхитектура
🔸 ПРОЕКТИРОВАНИЕ: С ЧЕГО НАЧИНАТЬ

Приятного просмотра 🫡

Ты знаешь кому переслать этот пост 👍

#unite2025@UniArchitect
#интервью@UniArchitect
YouTube Ярослав Шабанец: Клиентская архитектура корпораций Ярослав Шабанец — клиентский архитектор в компании Playtika. Ваш последний курс по архитектуре: https://course.uniarchitect.dev/y/75b7752 Подписывайся на мой блог в Telegram: https://t.me/+VAbytHEBGYMzYjAy На #unite2025 я времени зря не терял и успел записать…
  • 🔥 19
  • 👍 13
Post #149 5.29K
Оптимизации: рекомендации от Unity

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

Вот текстовая выжимка советов, что рекомендуют сами unity и другие разработчики:

1⃣ Отключайте Domain Reload для более быстрого запуска приложения.

Если есть баги связанные с сохранением старых значений в static переменных, делайте статический метод с атрибутом InitializeOnLoadMethod.

Не забудьте #if UNITY_EDITOR обернуть, иначе сборка билда упададет.

2⃣ Unity постоянно улучшают тулзы для профайлинга, он остановится проще и более информативным.

Чекните свежие версии 6.2, 6.3 (сейчас в бете), они добавили Highlights, которые помечают "долгие" кадры на которые стоит обратить внимание.
https://unity.com/features/profiling

3⃣ Если проект долго компилируется, можно при помощи Compilation Visualizer можно посмотреть порядок и время компиляции каждой asmdef в проекте.

Но скажу честно, сделать что-то с временем компиляции сложно.
Нужно либо значительно снижать количество asmdef в проекте, либо уменьшать количество кода 😅

4⃣ Контролируйте и удаляйте неиспользуемые shader variants и keywords.
Для этого можно использовать UnityDataTools - удобная тулза, которая распаковывает все ассеты из билда.

В случае если не удается избежать большого количества вариантов, прогревайте ваши шейдеры, чтобы избежать спайков на Instantiate.

5⃣ Project Auditor станет частью unity.
Это пакет, который анализирует ассеты, код, шейдеры, настройки и подсказывает на что нужно обратить внимание.

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

Я это к тому что советы и рекомендации, которые вы там увидите, я видел во многих репортах от unity об анализе проектов 😅

Да вот и все, каких-то новых открытий лично для меня не было.
База базовая. Или нет 🤔
Дайте знать в комментариях!

Ставь 👍, если тебе по кайфу такая движуха

#unite2025
  • 👍 72
  • 🔥 16
Post #148 3.71K
HTTP/2 в Unity 6.3

Наконец-то 🫡
Первую половину этого года я занимался как раз оптимизацией первой загрузки огромного и старого приложения.

Если коротко, там на старте качалось около 700 ассетов размером от 5kb до 5mb.
Около 150mb в общем.

И основная гипотеза была получении fast win за счет перехода с UnityWebRequest на BestHTTP, который поддерживает http/2.

Основная разница, которая полезна в играх:

1⃣ Размер запроса для мелких запросов меньше. HTTP/2 позволяет переиспользовать одно TLS-соединение для множества HTTP запросов к одному домену. То есть публичный ключ/сертификат и установка сессии TLS происходят один раз, а не для каждого запроса.

2⃣ И второй важный момент - запрос на DNS сервер делается всего 1 раз для одного домена вместо похода каждый раз.

На слайде ребята упомянули улучшение перфа на серверной стороне ... имеет место 100%, но для нас, unity разработчиков, есть хороший повод попробовать принести value в скорости загрузки наших игр 😊

Не уверен, но по секрету, я для unity команды делал закрытый Proof of Concept с тестами скорости загрузки через http/1 и http/2.
И unity приняли эту информацию т.к. цифры оказались убедительными.

Так что есть не иллюзорный шанс, что к появлению этой фичи я приложил руку 🥰
Офигеть ... новый пункт в резюме получается 🤣

#unite2025
  • 🔥 44
  • 👍 18
  • 🤯 5
Post #147 3.24K
CoreCLR в Unity быть

Другой вопрос когда и в каком виде.
У ребят есть планы завозить новый backend постепенно.

Как мне показалось, процесс будет похож на то что мы видели с Burst, Jobs и Entities.
Сначала все вышло в виде preview пакета в который постепенно завозилась новая функциональность в течении ... 4-5 лет, я уже и не помню.

Т.е. ещё раз, если и завезут, то точно постепенно и с постепенной докаткой фичей, совместимости и фиксов.

Что будет с mono не сказали.

Но я бы поставил 100€, что отключать старый backend не будут, как не убрали GameObject'ы заместив их ECS системой.

А что вы думаете, дайте знать в комментариях, а я пойду помучаю подробностями людей из unity 🤓

#unite2025
  • 🔥 19
  • 👍 5
  • 🤷‍♂ 4
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →