Розширення для Unity editor: базовий сетап проєкту. Автоматизація
Привіт! Я Красніков Данііл, Unity Developer у VOLMI — A Virtuos Studio.
Останнім часом мені подобається займатися прототипуванням. Мати можливість швидко перевірити ідеї «Чи працюватиме ця механіка в реальному проєкті» та «Чи буде цікаво мені це робити» завжди допомагає розвиватися (ну або як мінімум весело провести час). Проте створення нового проєкту, інсталяція всіх пакетів, налаштування кожного з них... Monkey job і цього ніяк не уникнути. Хоча є дещо...
Сьогодні ми з вами розберемося, як створити кастомний пакет, який буде автоматично виконувати всі звичні дії для сетапу проєкту.
Традиційний дисклеймер: рішення та код можуть бути не найкращими, тож для когось це буде гайд, а для когось план «як робити не треба». Також головна ціль тексту — показати, що і як просто можна створити засобами Unity та C#. Тож не судіть строго)
Мета
Спочатку треба визначитись, що ми хочемо отримати в кінці. Для себе я виділив такі пункти:
— Швидка інсталяція
Я не хочу вишукувати кожен пакет, який мені потрібен. А в процесі розробки виявилося, що їх так-то багато.
— Можливість швидко поміняти список «а що мені треба» та оновити його в усіх місцях
Кожен місяць в асет сторі та на гітхабі з’являється куча корисних асетів. Після використання деяких з них у мене в голові з’являється думка «так, без цього я більше не можу жити».
— Виставлення неймспейсу
Не знаю як вас, але для мене це нереально багато кроків: Edit->Project Settings->Editor->Root namespace = Project Name.
По суті, для вирішення цих проблем, треба створити кастомний пакет-провайдер. Роль його проста та очевидна: швиденько поставив і кліком декількох кнопок запустив інсталяцію всіх пакетів та асетів.
Але пакет провайдер також треба вишукувати та завантажувати, що може з часом дратувати. Тим паче якщо це архів чи файл .unitypackage.
Створення пакету
Видихаємо, але не стогоном мученика: в документації Unity є розділ Creating custom packages. Він то нас і врятує. Все просто:
- Створюєш репозиторій
- Додаєш ліцензію, ченджлог та рідмі
- Створюєш маніфест — основний файл, за яким Unity розуміє, що це пакет і отримує інформацію про нього.
Потім виділяєш дві основні папки: Runtime (логіка, яка піде в білд) та Editor (чисто функціонал едітора). Повний рекомендований layout з документації виглядає так:
Повторімо його в юніті:
А тепер детальніше по кожному файлу. Обов’язковим тут є тільки package, тож почнемо з нього.
По суті своїй це звичайний json. Опис кожного поля можна знайти в документації, але для валідної структури достатньо лише імені у форматі com.[назва організації].[назва пакету] та версії:
{ "name": "com.daniilcoolukraine.projectsetuptools", "version": "1.0.0", }
Мікро-уточнення: в імені не використовуються великі літери та спеціальні символи.
Поверх цієї структури я накинув ще ім’я, опис, автора та посилання на доку+ченджлог.
{ "name": "com.daniilcoolukraine.projectsetuptools", "version": "1.0.5", "displayName": "Project Setup Tools", "description": "Package contains references to all default things, that can be useful for developing a Unity project from scratch", "author": { "name": "DaniilCoolUkraine" }, "changelogUrl": "https://github.com/DaniilCoolUkraine/ProjectSetupTools/blob/main/CHANGELOG.md", "documentationUrl": "https://github.com/DaniilCoolUkraine/ProjectSetupTools/blob/main/README.md" }
Наступним йде readme. Він відображається в гітхабі, тож порад як і чим його заповнити існує безліч. Особисто я використав його як документацію та опис «що саме робить цей пакет».
Changelog цілком проста річ: версія та опис змін. Як і в рідмі, тут використовується markdown, тож можна досягти максимально красивого форматування. Наприклад отак:
## [1.0.0] - 2025-03-06 ### First release - base project setup and initial test
Ліцензія — це найпростіший крок. В гуглі знаходите ліцензію, яка підходить вам, та вставляєте в файл. Я за все опенсорсне, тож використав MIT ліцензію, але їх набагато більше. Взяти текст та ознайомитися з умовами можна тут Licenses | Choose a License.
Папки едітора та рантайму також потребують додаткового сетапу: треба створити їм власну assembly definition. По налаштуванням та неймінгам проходитись не буду, літератури в інтернеті на це предостатньо.
Пункт один виконаний: ми маємо порожній, але цілком валідний пакет, який можна закинути на гіт та інсталювати в будь-яке місце. Як саме? Просто скопіювати посилання, яке використовується для клонування репозиторію та вставити його в пекедж менеджер.
Asset importer
Тепер зробимо імпортер.
Насправді, частина «мені точно треба ось це в проєкті» буде різною для кожного дева: хто що купив та який підхід любить більше. Але для мене це точно: Odin, Unitask, Zenject, Tween-бібліотеки, власна реалізація EventBus, іконки компонентів в ієрархії та віконце обраних файлів.
І... всі ці речі імпортуються по різному. Тому об’єднаємо їх у дві групи за правильною термінологією.
Все, що прилітає з асет стору, зберігається як .unitypackage на диску у конкретного користувача. Це приблизно тут C:\Users\[User]\AppData\Roaming\Unity\Asset Store-5.x\. І звуться вони assets. Все, що прилітає з гіта, за принципом, який я описував вище, — це packages.
Подушніли, йдемо далі.
Щоб імпортнути асети, юніті має для нас чудове апі — AssetDatabase.ImportPackage. Параметрами ми передаємо шлях до асета (конкретно .unitypackage файл) та булку, якою можна заглушити віконце вибору. Загалом сніпет простий, тож залишу його без пояснень:
public static void ImportAssets(string asset, string folder) { var basePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); var assetsFolder = Path.Combine(basePath, "Unity/Asset Store-5.x"); AssetDatabase.ImportPackage(Path.Combine(assetsFolder, folder, asset), false); }
Імпорт пакетів вже трошки tricky тема. Спочатку варто зробити чергу всіх пакетів, потім витягати їх один за одним через едітор веб реквест. Якщо не закомплітилось — чекаємо ще. Коли отримали пейлоад, стартуємо наступний процес:
private static async void StartNextPackageInstall() { request = Client.Add(packagesToInstall.Dequeue()); while (!request.IsCompleted) await Task.Delay(10); if (request.Status == StatusCode.Success) Debug.Log($"Installed {request.Result.packageId}"); else Debug.LogError($"{request.Error.message}"); if (packagesToInstall.Count > 0) { await Task.Delay(1000); StartNextPackageInstall(); } }
Ііііі... це працює через раз. Імпорт пекеджа стартує компіляцію, яка діспозить реквести. В результаті воно встигає поставити
І останнє — виставлення неймспейсу. Тут все вирішується однією строчкою: EditorSettings.projectGenerationRootNamespace = PlayerSettings.productName.Replace(" «, »").
Висновки
В результаті ми повинні отримати щось таке: DaniilCoolUkraine/ProjectSetupTools. На цьому репозиторії я триматиму актуальну (та, сподіваюся, робочу) версію розширення. За бажанням до всього описаного можна докинути автоматичне створення папок з мого іншого допису (отут: Розширення для Unity editor: базовий сетап проєкту).
На цьому загалом і все. Діліться думками, власними мастхев-пакетами та робіть форки для власних автоматичних сетаперів. До зустрічі)
3 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів