- PVSM.RU - https://www.pvsm.ru -
Совсем недавно я осознал, что с ростом числа готовых проектов все больше времени приходится посвящать сборке билдов. Нельзя сказать, что юнити как-то сильно усложняет этот процесс, но уж точно и не упрощает. Особенно когда каждый проект собирается под несколько платформ да еще и в разных конфигурациях. В принципе проблема не нова и имеет множество разных решений. Но по ряду причин я остановился на написании собственного плагина.
Выглядит он примерно так:
А зачем, почему, где взять и как пользоваться я расскажу ниже.
Первый дискомфорт как правило ощущается, когда к релизу готовится более одной платформы. Выясняется, что в юнити какие-то настройки проекта общие для всех платформ, а какие-то нет. И это нужно всегда помнить и учитывать. Но в целом жить можно.
Потом обнаруживается, что нет возможности сохранять разные настройки в рамках одной платформы. Простой пример: билд один, а площадок, на которых он будет распространяться, много. И под каждую нужно что-то свое. Частично эта проблема решается выносом настроек в рантайм конфигурацию в StreamingAssets. Но лишь частично, ибо так можно конфигурировать только происходящее уже внутри игры. Иконку таким способом не подменишь. Иконку каждый раз нужно менять самому. Кодом ли, руками ли, но самому. Да и в какой-то момент, ответственный менеджер, которого вы месяц обучали работать со StreamingAssets уходит в отпуск, а билды нужны вчера.
Еще позже вы узнаете, что планируется отдельная корейская версия, там вообще все должно быть иначе и без #ifdef тут уже не обойтись.
А потом вам говорят, что игру нужно запускать на мобильные платформы, плейстейшн, нинтендо и стиральные машины.
В итоге подготовка каждого нового билда со временем становится похожей на это:
Проверить показания приборов, включить тумблер слева, повернуть рычаг справа, закрутить красный вентиль. Ничего не перепутать и не забыть.
Поначалу еще может и ничего, но быстро утомляет. Да и вспомни все манипуляции через месяц-другой.
Интернеты и народная мудрость предлагают нам следующее:
Решено. Пишем свой плагин, с UI и феями.
Для начала нужно определиться что мы собственно хотим получить и зачем.
Основной частью нашего плагина является работа с настройками проекта, а так же хранение и обработка индивидуальных настроек вариантов. Поэтому сконцентрируем внимание именно на этом.
Все настройки юнити хранит в директории ProjectSettings в корне проекта. И первым делом при инициализации мы сохраним эти настройки в директории плагина (к слову это BuildVariants в корне проекта). Это потребуется для того чтобы мы могли отслеживать все последующие изменения. Далее нам нужно их как-то хранить. Самым простым было бы просто копировать ProjectSettings в отдельное место под каждый вариант. И в момент его активации просто подменять их целиком. Идея вполне рабочая и поначалу я рассматривал именно ее. Но это полностью лишает нас возможности наследовать варианты. И если мы уже пишем плагин, то будем сразу делать красиво. Значит нам нужно научиться читать и писать содержимое ProjectSettings.
Для этого нужно понять, что же такое там хранится. А хранятся там самые обыкновенные ассеты, которые сериализуются и десереализуются штатным образом. Это значит, что мы можем прочитать их через AssetsDatabase и получить SerializedObject. Это уже что-то. Потому что мы можем пройтись по всем SerializedProperty, отследить их различия с исходным "снимком" и сохранить их в варианте. Потом при сборке или активации варианта мы собираем изменения по всей цепочке наследования, применяем их к "снимку" и подсовываем в ProjectSettings. Вуаля.
Но у SerializedProperty есть некоторые неприятные особенности: способ хранения значений (все эти intValue, floatValue, isArray), отсутствие нормального механизма их сравнения (есть два родственных объекта, как нам понять все ли SerializedProperty у них имеют одинаковые значения) и парадоксальное (а может и нет) отсутствие аттрибута Serializable (а значит для сохранения нам нужен будет какой-то враппер). Не могу сказать, что это какие-то фатальные недостатки, Все это делалось и не раз в многочисленных editor скриптах. Но хочется все же чего-то более простого, понятного и универсального.
А может быть мы немного ограничим применение нашего плагина? Пусть он работает только на проектах с текстовой сериализацией ассетов (а кто-то еще пользуется бинарной?). Тогда все ProjectSettings будут храниться в виде yaml документов. Можно взять библиотеку YamlDotNet и с ее помощью парсить и сохранять настройки. Заодно и свои конфиги хранить в yaml. Так даже нагляднее. Нужно только дописать немного расширений для диффов yaml документов и их объединения.
Немного возни с editor window (даже описывать не хочу, надеюсь, что с UIElements жить станет проще и веселее), сбор всего в кучу и готово.
Самое время показать, что же у меня получилось [1]. С основными механизмами работы плагина вы уже ознакомились, поэтому далее тезисно о каких-то особенностях:
$unity_path -batchmode -projectPath $project_path -quit -logfile -executeMethod BuildVariants.Controller.BuildController.BuildCollection -collection standalone
Конечно же хочется кормить плагин фичами до бесконечности, но пора возвращаться к реальным проектам, а заодно тестировать имеющийся функционал. Чуть позже хочу применить UIElements для свежих версий юнити, надеюсь это позволит сделать все более красиво и удобно. Хочется еще прикрутить версионирование и некое подобие переменных окружения. Может быть общественность подскажет что-нибудь еще по функционалу или юзабилити.
Поэтому буду рад любым пожеланиям, замечаниям, вопросам и баг репортам. Легких билдов вам!
Автор: utkaka
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/continuous-integration/302524
Ссылки в тексте:
[1] что же у меня получилось: https://github.com/utkaka/UnityBuildVariants
[2] Источник: https://habr.com/post/433460/?utm_campaign=433460
Нажмите здесь для печати.