cookie

نحن نستخدم ملفات تعريف الارتباط لتحسين تجربة التصفح الخاصة بك. بالنقر على "قبول الكل"، أنت توافق على استخدام ملفات تعريف الارتباط.

avatar

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

Авторский блог unity lead'a. Пишу про архитектуру проектов и свой путь. По всем вопросам писать: @vangogih

إظهار المزيد
مشاركات الإعلانات
1 469
المشتركون
+324 ساعات
+207 أيام
+4630 أيام

جاري تحميل البيانات...

معدل نمو المشترك

جاري تحميل البيانات...

test
إظهار الكل...
Магазин
С ПОЛЕЙ РАЗРАБОТКИ: REVERT MERGE COMMIT Я работаю с git только через консоль. Мне не нравятся все GUI, которые имеются на рынке. Т.к. часто они плохо решают узкие, сложные кейсы, которые порой возникают. Текущий пост прекрасный тому пример, ибо через git GUI встроенный в райдер я не смог решить проблему ниже. Ситуация: Есть баг, которые вы правите перед релизом. У вас в голове два решения: 🔸 По уму, но дольше и большим объемом регресса. 🔹 Поправить точечно, грязно, но быстро, внедрившись в другую систему. Конечно как и подобает доблесть, выбираем первый вариант. Делаем фикс, примерно в 3-6 коммитов, проверяем в редакторе, отправляем в QA. И вроде опыта достаточно, много всего знаешь и проверил все перед заливкой, но: 🔹 На мобилках фикс не работает. Там другое графическое API, отличное от редактора и там твой баг вообще не исправлен, а наоборот приводит к hard lock'ам из-за неправильной сортировки UI элементов в очереди на отрисовку. И вот вы с лидом (или как лид) думаете как исправить это. Изменения расползлись по другим веткам, а с момента вашего merge commit'a уже прошло пару дней. Надумали два путя: 🔹 Удалить фикс всех веток. Можно сделать как через rebase всех изменений после ваших изменений, а потом force push'ем обновить все ветки. Можно ручками сделать cherry-pick, а потом force push'ем обновить все ветки. 🔹Сделать revert merge коммита. Проблема с первым: 🔸Придется блокировать работу во всех ветках на время отката. 🔸Во время rebase могут возникнуть конфликты из-за которых можно накуролесить на --выходные и ++пара бессонных ночей. Со вторым проблема в том, что ХЗ как сделать revert целого merge'а. И ответ совсем не очевидный: git revert -m 2 или 1 <merge_commit_hash> С revert понятно, а что за магия с 2 или 1? Приготовьтесь, инфу про git оч сложно запаковывать компактно 😅 git — это направленный ацикличный граф, ноды которого всегда хранят в себе hash родителя(-ей). Т.е. каждый git commit -m "the best changes" создает новую ноду в которую записывает hash parent коммита (hash коммита предшествующий текущему) и hash object-tree. Для простоты понимания git — это два независимых LinkedList'а один - для изменений (object-tree) второй - для коммитов (commit-tree). Только LinkedList'ы однонаправленные (нету Next) и могут иметь несколько нод (Node<T>[] Previous). Это значит: 🔸 Все коммиты в ветке однонаправленно связаны с самым первым Initial commit. Т.е. из любого коммита в ветке можно дойти до самого начала графа. 🔸 Каждый коммит, без указания parent'а, как нода из LinkedList'а, Previous которой равен null. Угадайте как их можно удалить? 🙃 🔸 Эта структура отлично подходит для добавления/изменения/удаления. С поиском сложнее, но благодаря сортировке префиксов по алфавиту (см. папку objects), используется бинарный поиск. С устройством разобрались. Дальше порядок работы merge: 1️⃣ Находим общий коммит. Просто идем по графу, пока parent'ы не совпадут. 2️⃣ Ищем diff от общего коммита до последних коммитов в двух ветках. 3️⃣ Полученный diff пишем в merge-commit. 4️⃣ В parent у merge-commit'a прописываем последниE коммитЫ из двух веток. Т.е. merge-commit, в отличии от обычного имеет 2 parent'а. Это фактически значит: 🔻git merge не меняет родителей у существующих коммитов (в отличие от rebase), а создает новый, с ссылками на 2 последних коммита в ветках. А revert-commit может иметь лишь один parent. Значит, чтобы сделать все правильно, нужно указать изменения какого именного из parent'ов мы хотим revert'нуть. Или по другому: diff какой из ветки мы должны revert'нуть За это как раз и отвечает магическое 1 или 2 — номер parent'а, изменения которого мы хотим revert'нуть. Лично у меня случилось 2 озарения: 🔶 Именно merge-commit несет в себе все изменения. Revert'нули его == revert'нули изменения всех коммитов. 🔶 Все, rebase, cherry-pick есть маленькая merge операция. А не наоборот. До этого я думал что merge - аналог rebase 🤯 Но помните, вы этим самым, вы делаете revert изменений, не истории. Ставь 👍 если такая движуха тебе по кайфу! Источники: Ответ с SO Статья раз Статья два @UniArchitect #будни
إظهار الكل...

👍 23🔥 6
С ПОЛЕЙ РАЗРАБОТКИ: REVERT MERGE COMMIT Сейчас на работе прои https://stackoverflow.com/questions/7099833/how-do-i-revert-a-merge-commit-that-has-already-been-pushed-to-remote
إظهار الكل...
How do I revert a merge commit that has already been pushed to remote?

git revert <commit_hash> alone won't work. Apparently, -m must be specified.

ЦЕЛЬ Каналу стукнул год ❤️‍🔥 Много всего получилось сделать за это время: — 90+⭐️ Шаблон пустого проекта с архитектурой, которую я стараюсь использовать на всех своих проектах — ~50⭐️ Плагин для миграции json файлов — 2 статьи на хабр: - Архитектура unity проектов - Миграция json файлов — Написать несколько полезных welcome статей в другие каналы: - Полиморфизм системы - UnityEngine.Object == null - Архитектура и рендерПосетить DevGAMM Lisbon — Помочь найти работу одному крутому senior'у 😎 — Набрать 1400 крутых, активных подписчиков В общей сложности я написал около 50 содержательных постов, где постарался поделиться своим опытом и подходом к архитектуре. Не стесняйтесь пользоваться навигацией, за год было куча всего, что вы могли пропустить 😉 За такой большой промежуток времени сложно быть последовательным если нет принципов по которым ты пишешь статьи. Я для себя сформулировал их так: 🔸 Удобство чтения Каждая мысль отделена отступом, каждые важный пункт выделен 🔸 Экономия времени читателя Статьи должны экономить время, давая максимальную пользу. Выводы должны быть однозначны и соответствовать выводам из источника. 🔸 Качество важнее времени Не пытаться выдавить контент в какой-то срок. Писать по кайфу, когда есть силы и желание. И не важно сколько времени прошло с последнего поста. Я не планирую заканчивать работать над блогом, а наоборот, хочу его развивать. Моя цель: 🔻 Создать единое место откуда разработчики с 1+ год коммерческого опыта работы с unity смогут найти всю информацию касательно сложных технических нюансов при работе с unity. Все мы в знаем о таких блогах как: Catlike Coding, JacksonDunstan, Alan Zucconi Я как самоучка вычитал все эти блоги вдоль и поперек. И как никто другой хочу не только брать, но и отдавать. Потому за следующий год я планирую: 🔹 Запустить сайт-блог 🔹 Объединить идею качественных статей с качественными курсами 🔹 Полученные ресурсы использовать, для того чтобы писать статьи, видео, которые будут экономить время на самостоятельное погружение в узкие и сложные темы И чтобы воплотить столь амбициозные планы, мне понадобятся ресурсы. Потому с этого года, изредка, может раз в месяц тут будут появляться нативные посты с рекламой событий или других блогов, которые могут быть полезны. Отбор будет максимально жестким, я не собираюсь разменивать лояльность читателей и подрывать доверие. Так что это только начало, человек я амбициозный и терпеливый. Уверен что все получится 💪 Спасибо каждому за то что остаетесь со мной 🥰 Ставь 👍 тебе по кайфу такая движуха! @UniArchitect
إظهار الكل...
👍 72🔥 22 3 3 1
ИНКАПСУЛЯЦИЯ Кажется, у нас есть еще один претендент на звание "лучший повод развести холивар". До этого с этим отлично справлялись несколько известных аббревиатур. Озвучив который, можно было смачно так разочароваться в любом человеке. И мне кажется, что причина этого лежит в возможности по-разному трактовать то или иное понятие. Сейчас я изучаю, как подходы к архитектуре ПО менялись с течением времени. В связи с этим читаю много статей и литературы. И от одного источника к другому, я замечаю, как одно и то же понятие несет в себе так много смыслов, что его использование автоматически вводит в сильное замешательство. Инкапсуляция. Давайте просто посмотрим на определения: 🔹 Русскоязычная википедия.
процесс разделения элементов абстракций, определяющих её структуру (данные) и поведение (методы)
🔷 Англоязычная википедия.
объединение объекта и его метода с данными
🔹 Другой ресурс, тоже вики, специализирующийся на разработке ПО.
процесс объединения элементов для создания нового объекта
При том в научных статьях, книгах и блогах известных специалистов сохраняется точно такая же путаница: 🔸 Статья на которую ссылаются другие 23 статьи в которой:
инкапсуляция используется для создания абстрактных типов данных, которые можно изменять только через их внешний интерфейс.
🔸 Мартин Фаулер
Это говорит о том, что поля объекта не должны быть общедоступными, вместо этого весь доступ извне объекта должен осуществляться через методы доступа.
🔸 Bertrand Meyer в книге Object-Oriented Software Construction вообще говорит что это синоним Information Hiding Не обязательно ходить по всем перечисленным источникам. Я лишь хочу подсветить проблему: 🔻У нас НЕТ нормального/единого определения такого базового термина как инкапсуляция! Т.е. при работе в команде, упоминая данный термин, вы должны держать в голове ворох расплывчатых определений, чтобы понять, что имеет в виду другой человек. Точно так же с чтением книг и статей. Многие авторы, при этом, не чураются надумать себе какое-то 3 определение и найти тайный смысл. Изучая, пробираясь через весь этот ворох, для себя я сделал пару выводы: 1️⃣ Каждый раз при упоминании данного термина, желательно уточнить у другого человека, что он имеет в виду. 2️⃣ Каждый раз, видя это термин в книге/статье, подбирать подходящее определение и пытаться понять, что хотел сказать автор 🤬 3️⃣ Я перестану употреблять этот термин. Чтобы не вводить никого в заблуждение. Вместо него просто буду использовать синонимы, которые отлично отражают суть: 🔸 Модификаторы доступа, интерфейс, абстракция: в случае если хочу сказать про сокрытие/ограничение доступа 🔸 Представление объекта в памяти, виртуальная таблица, объединение методов и данных: для случаев, когда захочу описать особенности ОО языка Ну и если я могу дать рекомендацию: 🔻 Держите в голове суть беседы, обсуждения, разговора, а не корректность терминов, когда говорите о разработке. Как по мне, это отличный показатель того, на сколько большой путь еще предстоит проделать разработке как инженерной дисциплине. Что супер! У всех нас есть еще куча времени, чтобы вписать себя в историю 😜 Ставьте 👍 если заходит подобного рода контент! @UniArchitect #аббревиатуры
إظهار الكل...

43👍 22🤔 1 1
ПОЛИМОРФИЗМ СИСТЕМЫ Не то что бы мы (инженеры программисты) можем превращать воду в вино. Скорее нет ограничений как таковых в решении любой задачи. Давайте представим. У вас есть любой язык программирования. Что вы на нем НЕ сможете написать? Конечно, есть ряд проблем, которые не возможно решить за конечное время. Но это не значит, что решения нет или что его нельзя написать. Но мало того, что задач, которых нельзя решить, нет, так еще и вариаций решений одной проблемы может быть сколько угодно много. 🔹Давайте порассуждаем глобально, без привязки к языку/платформе. Для простоты возьмем самую примитивную задачу: "Вывод Hello World на экран". Сколько вариантов решений вам приходит в голову? Мне из-за проклятия знаний даже сложно представить, сколько их. Потому мой ответ: а какие ограничения? 🔸Этим всем. Я подвожу к мысли:
У любой задачи несколько решений. И мы, анализируя внешние факторы и время, склонны выбирать наиболее эффективное в данный момент.
Назовем это полем решений S (solutions). 🔸Любое решение можно проектировать по разному. При том вариантов дизайна может быть сколько угодно. Назовем это поле вариантов дизайна D (design). Например: — Под каждый char заведем свой класс. Сделаем fluent builder, который будет собирать нашу строку посимвольно. 🔸Ну и наконец у каждого решения есть поле реализаций (имплементаций). То как эта задача может быть фактически написана. Назовем это — I (Implementation). Пример: — Каждый char представим в виде ASCII кода, запишем в массив и при выводе сконвертируем коды в символы. — Или напишем свой рендер символов в консоли 🔻Отсюда 1ый принцип инженерной разработки:
Каждая задача имеет поле возможных решений, которое является произведением поля возможных реализаций и поля возможных дизайнов. - Wang, Software Engineering Foundations, p.33, Theorem 1.6
В виде формулы это будет выглядеть так: S = D * I Это подводит к вопросу, а насколько велики D, I и S? — Много велики. Потому что (D * I) -> ∞. А на поле решений влияют многие факторы, такие как: — Выбранный ЯП. — Code style. — Модели данных. — Маршалинг объектов в память. Любое изменение будет приводить к другой(-му) реализации/дизайну решения. 🔻Из этого следует очень важный вывод, от которого болит у всех:
Трудно технически и/или экономически доказать что программа имеет единственно верное рациональное решение в поле возможных решений. Это более известно как: не существует единственно верного решения - Wang, Software Engineering Foundations, p.33, Corollary 1.4
Это одно из фундаментальных ограничений, с которым мы имеем дело каждый день. А называется оно — полиморфизм системы. И ограничение это когнитивное, т.к. завязано на фундаментальное ограничение человеческого мозга (про ПРОДУКТИВНОСТЬ я уже писал) 🔸Ну и, говоря простым языком: — Любые споры, распри, негативные эмоции из-за вариантов решения не имеют смысла на фундаментальном уровне. Т.к. любая сторона не сможет доказать однозначное преимущество одного решения над другим. Вы знаете, кому отправить этот пост 🛞 Ставь 👍 если тебе нравится такая движуха Ссылка на цитируемую книгу @UniArchitect #software_engineering
إظهار الكل...

👍 30 8🔥 3
👀🗑Сборка мусора в Unity? Путь GC.Collect(). Давайте проследим некоторый путь. Путь GC.Collect(). Но сначала. Что такое GC.Collect()? Это принудительный вызов сборки мусора. Во что превращается GC.Collect? Ведь мы знаем, что Unity использует другой сборщик, который называется Boehm GC, а следовательно GC.Collect должен во что-то транслироваться. Чтобы ответить на этот вопрос, нужно проследить путь преобразования кода. 1️⃣ Давайте напишем простой класс (Убираю лишние переносы в целях экономии места в посте; Длинные имена, сокращены для простоты чтения ):
public class Minutri : MonoBehaviour {
    private void Start() {
        GC.Collect();
        GC.Collect(2, GCCollectionMode.Forced);
    }
}
Два разных вызова — чтобы посмотреть, куда уходит двойка, а куда GCCollectionMode.Forced. GC.Collect(2, GCCollectionMode.Forced) говорит о том, что нужно вызвать сборку вплоть до второго поколения с forced. Но не забываем — мы работаем с Boehm GC. Поэтому про работу с поколениями не может идти речи. Как же получается? Написать так можно — а поколений нет. Смотрите далее) 2️⃣ После трансляции IL2CPP находим метод Start класса Minutri. Называется он у меня Minutri_Start_... 3️⃣ В Assembly-CSharp.cpp наблюдаю, во что превратился метод:
void Minutri_Start_ (Minutri_t* __this, ) {
static bool s_Il2CppMethodInitialized; // <------ а
GC_Collect_m(NULL); // <------ б
GC_Collect_m(2, 1, NULL);
return;
Интересовать нас может сразу два пункта: а) Видим использование static bool. Напоминаю — это медленно. б) Оба метода GC_Collect раскрылись, мы их наблюдаем, и они похожи. 4️⃣ Идем глубже, в методы GC_Collect_m...
void GC_Collect_m() {
static bool s_Il2CppMethodInitialized;
L_0 = GC_get_MaxGeneration_m(NULL);
GC_InternalCollect_m(L_0, NULL);
}
а) Опять static bool. б) Воу 🤨 Все-таки получаем максимальное поколение. Получается, я вам врал! Какой ужас. (нет) в) Вызываем GC_InternalCollect_m и передаем туда "максимальное поколение". Давайте я вам помогу, и мы не будем заходить в GC_get_MaxGeneration_m. Он возвращает ноль. Но это и неважно. Сейчас все увидите. 5️⃣ Зайдем глубже, в GC_InternalCollect_m. Мы видим метод. Там опять нам всё не нужно, кроме одной строки:
(()mscorlib::System::GC::InternalCollect) (___0_generation);
Заходим в InternalCollect. Далее в Collect(generation) 6️⃣ Ну что ж. Мы пришли, поздравляю!) Метод Collect перед вами целиком:
void il2cpp::gc::GarbageCollector::Collect(int maxGeneration) {
#if IL2CPP_ENABLE_DEFERRED_GC
    if (GC_is_disabled())
        s_PendingGC = true;
#endif
    GC_gcollect();
}
Тут, как мы видим, всё: последнее упоминание поколений. Глубже мы не пойдем. Вы видите, чтобы maxGeneration параметр где-то использовался? Вот и я не вижу. Зачем они так сделали? Вероятней всего для того, чтобы в случае использования другого GC можно было быстро перейти на поколения. Так, а что у нас с GC.Collect(2, GCCollectionMode.Forced)? Там пойдут goto и прочие вещи, которые здесь не буду рассматривать, так как не хватит места в посте. Но, короче говоря: в нем будет вызов этого же Collect из пункта 6️⃣. То есть, что бы мы ни указывали в аргументы GC.Collect — это не имеет значения. Резюмируем: — GC в .NET C# поколенческий, в Unity - нет — Вызов сборки мусора конкретного поколения вызывает сборку мусора в целом — Перегрузки GC.Collect, при настройке билда в IL2CPP не влияют на перформанс и ничего не ломают P.S. Может быть я был не прав, и мы посмотрели что-то неверно? Давайте, как люди, которые хотят докопаться до сути, обратимся к первоисточнику, и посмотрим на ответ Josh Peterson'а. В ходе диалога, я задал вопрос о том, используют ли юнитеки поколения в Boehm? Был дан ответ:
"Currently Unity does not use the generational GC in Boehm. I suspect that we might be able to use it, but we don't have any active plans to enable that for now".
Анализ трансляции GC.Collect подготовлен специально для @UniArchitect Об устройстве GC в Unity, о IL2CPP, CI/CD и не только я пишу в своем авторском telegram канале. Подпишись!🔥
إظهار الكل...
👍 33 7💯 3
МЫ ИНЖЕНЕРЫ, НЕ ХУДОЖНИКИ 🔹 Разработка ПО не имеет теоретической базы, как математика например 🔹 Разработка ПО это не инженерная дисциплина, скорее творческая, как живопись 🔹 Каждый может программировать. Дети иногда даже лучше чем взрослые 🔹 Каждый кто смог вывести в консоль "Hello World" может быть уверен в том, что он/она программист Каждый кто согласен хоть с одним утверждением выше, скорее всего не имел дело с достаточно объемными программами (проектами) от 5000 до 10000 строк (LOC - Lines Of Code) в размере. Это эквивалентно книге в которой 100 страниц это код на ЯП высокого уровня и документацией. И это лишь минимальный порог, когда мы можем считать программу достаточно сложной.
Wang, Software Engineering Foundations, p.13
Средняя игра на soft launch этапе, примерно с неделей геймплея имеет размер около 60-100к строк кода. Крупные проекты, уже находящиеся на этапе поддержки больше года, от 150к строк. И это без учета кода самого игрового движка. Работа в таких проектах без стандартов, систем, принципов, передовых практик просто не возможна. Потому что ведет к неуправляемому росту сложности и как следствие — к невозможности контролировать сроки. А это 40% почему проекты терпят неудачу. Инженеры же, согласно IEEE/ACM: 🔸 Выполняют задачу, тщательно оценивая варианты, выбирая нужные подход и инструменты реализации 🔸 Делают измерения, итерируют и калибруют результаты, подтверждая правильность своих предположений 🔸 Уделяют особое внимание упорядочиванию (формализации) процесса 🔸 Создают принципы, стандарты и передовые практики и используют их Сколько утверждений выше согласуется с тем, что вы делали будучи программистом? Отсюда выводы: 🔹 Разработка ПО — инженерная дисциплина, а разработчики ПО инженеры, не художники 😅 🔹 Заблуждение выше возникло из-за непонимания того, что делает и какие проблемы решает программист 🔹 Потенциальное решение проблем при разработке может лежать в плоскости других инженерных дисциплин И есть раздел, рассматривающий разработку ПО как инженерную дисциплину:
Software engineering (SE) — инженерная дисциплина, которая изучает природу ПО, подходы и методологии крупной разработки, а так же теории и законы, лежащие в основе поведения ПО и практики разработки ПО. Wang, Software Engineering Foundations, p.23, definition 1.6
Как не странно, но начать писать про архитектуру проектов, не начав с базы — нельзя. Потому ближайшее время статьи будут на темы связанные с SE. Ставь 👍 если тебе нравится такая движуха @UniArchitect #software_engineering
إظهار الكل...

👍 77 20
РЕЛИЗ FastMigrations.Json.Net 10 месяцев назад я написал пост про версионирование приложения: ВЕРСИОНИРОВАНИЕ Ч.1 ВЕРСИОНИРОВАНИЕ Ч.2 И во второй части я пообещал переписать один уже давно не поддерживаемый плагин. Сделать его лучше, быстрее, сильнее 🤣 Многие из вас следили за разработкой в режиме реального времени у меня на стримах 👉Ссылка на плейлист👈 (есть субтитры на английском, так что смело закидывайте европейским коллегам 😅) По итогу, слово сдержал, пользуйтесь на здоровье ❤️ https://github.com/vangogih/FastMigrations.Json.Net Жмакайте на ⭐️, чтобы не потерять! Версия 1.0.3 — production ready, можно смело внедрять к себе в проекты 💪 🔻Что изменилось за кадром: 🔸 Сделал CI на github actions, который прогоняет тесты на 5 версиях unity 🔸 Для тестов включил вычисление test coverage и задеплоил результаты на github pages Кликните на бейджик Coverage, чтобы понять о чем это я 😜 🔸 Сделал отдельную сборку для benchmark'а Просто чтобы понимать на сколько быстрее. Так-то в 5-7 раз! 🔸 Сгенерил через всемогущий ИИ иконку Вот оно где будущее, когда прогеры могут нормальный логотипы для своих плагинов делать😂 🔸 Опубликовал плагин в nuget и openupm 🔸 Написал и оформил лучшее readme в своей жизни 🥺 Достаточно много осталось за кадром, но поверьте, по большей части там была монотонная работа, где я 95% залипал в документацию. Ибо с github actions, pages я работал впервые 🔻Что я лично для себя понял про подобного формата работу: 🔹 Нужно иметь выдержку и самодисциплину Честно, если бы я не пообещал и не начал всю эту активность со стримами, мне было бы сложно сохранить достаточный уровень мотивации чтобы закончить работу над плагином 🔹 Качественная упаковка open source плагина занимает около 50% времени от самой реализации Я понимаю что плагин не большой, всего 400 строк кода, но я явно недооценил сколько времени уйдет на оформление, CI/CD и документацию 🔹 Дисциплина кода, коммитов, архитектура даже для маленьких проектов важна Иначе чтобы сделать нормальный CI/CD без боли, придется перелопатить половину проекта Это было только начало, на стримах я упоминал что работаю сейчас над своими курсами по архитектуре, которые хочу зарелизить в этом году А до этого момента продолжу делиться инсайтами по разработке и архитектуре unity проектов! Всем огромное спасибо, без вас этого плагина не было бы 😘 Кстати, в репозитории есть открытые Issue, ошибки в readme и xml-doc'ах Не стесняйтесь внести свой вклад и стать contributor'ом 🫡 @UniArchitect
إظهار الكل...

🔥 34👍 2
СТРИМ Неожиданный пятничный, рабочий стрим! Я оч сильно закопался с плагином по миграциям и решил сделать из него конфетку. Я уже успел: 🔸Ускорить его в несколько раз 🔸Сделать много устойчивым для работы в многопотоке 🔸Написать бенчмарк и сравнить с аналогом 🔸Написать github actions, которые: 1. Запускают dotnet тесты 2. Запускают unity тесты на 5 LTS версиях 3. Пушат результаты покрытия тестов с метриками в github pages Мне правда хочется всеми деталями с вами поделиться и вместе дописать этот плагин. Но при этом не хочется подрубать стрим на youtube. Потому, через 20 минут подключайтесь прямо в телеге на стрим! Планы на стрим: 🔸Рассказать о всех улучшениях 🔸Рассказать про github actions что уже написаны 🔸Исправить ошибку деплоя результатов покрытия тестами 🔸Написать release пайплайн с генерацией .unitypackage, пушем nuget и npm пакетов и проставлением версии p.s. я в github actions и yaml файлы пишу впервые, потому оч сильно туплю местами) p.s.p.s. стрим в телеге - эксперимент, пойти не так может все что угодно! Но и пофигу, Пятница, расслабляемся) @UniArchitect
إظهار الكل...
Unity Architect: архитектура unity проектов

Авторский блог unity lead'a. Пишу про архитектуру проектов и свой путь. По всем вопросам писать: @vangogih

🔥 12👍 2 2
اختر خطة مختلفة

تسمح خطتك الحالية بتحليلات لما لا يزيد عن 5 قنوات. للحصول على المزيد، يُرجى اختيار خطة مختلفة.