Unity Package Manager

Unity - платформа, яка існує досить давно і постійно розвивається. Однак, працюючи в ній з кількома проектами одночасно, все ще можна зіткнутися зі складнощами у використанні загальних вихідних файлів (.cs), бібліотек (.dll) та інших ассетів (зображення, звуки, моделі, префаби). У цій статті ми розповімо про наш досвід роботи з нативним вирішенням такої проблеми для Unity.

Unity Package Manager

Методи поширення загальних ресурсів

Існує більше одного способу використовувати спільні ресурси для різних проектів, але кожен підхід має свої плюси та мінуси.

1. Дублювання – «руками» дублюємо ресурси між проектами.

Плюси:

  • Підходить всім видів ресурсів.
  • Немає проблем із залежностями.
  • Немає проблем із GUID'ами ассетів.

Мінуси:

  • Гігантські репозиторії.
  • Немає можливості версіонування.
  • Складність відстеження змін у загальних ресурсах.
  • Складність поновлення загальних ресурсів.

2. Підмодулі Git - Розповсюдження загальних ресурсів через зовнішні підмодулі.

Плюси:

  • Можна працювати з вихідними джерелами.
  • Можна розповсюджувати асети.
  • Немає проблем із залежностями.

Мінуси:

  • Необхідний досвід роботи з Git.
  • Git не дуже товаришує з бінарними файлами - доведеться підключати LFS.
  • Розмежування доступу для репозиторіїв.
  • Складнощі при підвищенні та зниженні версії.
  • Можливі колізії GUID'ів і немає однозначної поведінки з боку Unity для їхнього вирішення.

3. NuGet – поширення спільних бібліотек через NuGet-пакети.

Плюси:

  • Зручна робота з проектами, які не залежать від Unity.
  • Зручне версіонування та дозвіл залежностей.

Мінуси:

  • Unity не вміє працювати з NuGet-пакетами з коробки (на GitHub можна знайти NuGet Package Manager for Unity, який виправляє це, але є нюанси).
  • Труднощі при поширенні інших видів ассетів.

4. Unity Package Manager – поширення спільних ресурсів через нативне рішення для Unity.

Плюси:

  • Нативний інтерфейс для роботи із пакетами.
  • Захист від перезапису .meta файлів у пакетах при конфліктах GUID'ів.
  • Можливість версіонування.
  • Можливість розповсюдження всіх видів ресурсів для Unity.

Мінуси:

  • Досі можуть траплятися конфлікти GUID'ів.
  • Нема документації для реалізації.

Останній спосіб має більше переваг, ніж недоліків. Однак він зараз не дуже популярний через відсутність документації і тому ми зупинимося на ньому докладно.

Unity Package Manager

Unity Package Manager (далі UPM) – інструмент для керування пакетами. Його додали в Unity 2018.1 і він використовувався тільки для пакетів, які розроблялися Unity Technologies. Однак, починаючи з версії 2018.3, з'явилася можливість додавання кастомних пакетів.

Unity Package Manager
Інтерфейс Unity Package Manager

Пакети не потрапляють у вихідні частини проекту (директорію Assets). Вони знаходяться в окремій директорії %projectFolder%/Library/PackageCache і ніяк на проект не впливають, їх єдина згадка у вихідниках - у файлі packages/manifest.json.

Unity Package Manager
Пакети у файловій системі проекту

Джерела пакетів

UPM може використовувати кілька джерел пакетів:

1. Файлова система.

Плюси:

  • Швидкість реалізації.
  • Не потребує сторонніх інструментів.

Мінуси:

  • Складність версіонування.
  • Необхідний спільний доступ до файлової системи для всіх, хто працює з проектом.

2. Git-репозиторій.

Плюси:

  • Потрібен лише Git-репозиторій.

Мінуси:

  • Не можна перемикатися між версіями через вікно UPM.
  • Працює не з усіма Git-репозиторіями.

3. npm-репозиторій.

Плюси:

  • Повністю підтримує функціонал UPM та використовується для поширення офіційних пакетів Unity.

Мінуси:

  • В даний час ігнорує всі рядкові версії пакетів, окрім "-preview".

Нижче ми розглянемо реалізацію UPM+npm. Ця зв'язка зручна, оскільки дозволяє працювати з будь-якими видами ресурсів та керувати версіями пакетів, а також повністю підтримує нативний інтерфейс UPM.

Як npm-репозиторій можна використовувати Вердаччо. До нього є докладна документація, і для його запуску знадобиться буквально пара команд.

Налаштування оточення

Для початку потрібно встановити Node.js.

Створення пакету

Щоб створити пакет, потрібно розмістити файл package.json, який його описуватиме, в директорію з вмістом цього пакета. Потрібно зробити таке:

Перейти до директорії проекту, яку хочемо зробити пакетом.

Виконати команду npm init та під час діалогу ввести необхідні значення. Для name вказуємо ім'я у форматі реверс домену, наприклад com.plarium.somepackage.
Для зручного відображення імені пакета - додати властивість displayName до package.json і заповнити його.

Так як npm js-орієнтований, у файлі є не потрібні нам властивості main та scripts, які Unity не використовує. Краще видалити їх, щоб не засмічувати опис пакета. Файл має виглядати приблизно так:

  1. Перейти до директорії проекту, яку хочемо зробити пакетом.
  2. Виконати команду npm init та під час діалогу ввести необхідні значення. Для name вказуємо ім'я у форматі реверс домену, наприклад com.plarium.somepackage.
  3. Для зручного відображення імені пакета - додати властивість displayName до package.json і заповнити його.
  4. Так як npm js-орієнтований, у файлі є не потрібні нам властивості main та scripts, які Unity не використовує. Краще видалити їх, щоб не засмічувати опис пакета. Файл має виглядати приблизно так:
    {
     "name": "com.plarium.somepackage",
     "displayName": "Some Package",
     "version": "1.0.0",
     "description": "Some Package Description",
     "keywords": [
       "Unity",
       "UPM"
     ],
     "author": "AUTHOR",
     "license": "UNLICENSED"
    }

  5. Відкрити Unity і згенерувати .meta файл для package.json (Unity не бачить асети без .meta файлів, пакети для Unity відкриваються лише для читання).

Надсилання пакету

Для надсилання пакета необхідно виконати команду: npm publish --registry *адрес до хранилища пакетов*.

Встановлення та оновлення пакетів через Unity Package Manager

Щоб додати пакет до Unity-проекту, потрібно:

  1. Внести до файлу manifest.json інформацію про джерело пакетів. Для цього необхідно додати властивість scopedRegistries та вказати скоупи та адресу джерела, за яким шукатимуться конкретні скоупи.
    
    "scopedRegistries": [
       {
         "name": "Main",
         "url": "адрес до хранилища пакетов",
         "scopes": [
           "com.plarium"
         ]
       }
     ]
    
  2. Перейти в Unity та відкрити вікно Package Manager'а (робота з кастомними пакетами не відрізняється від роботи із вбудованими).
  3. Вибрати All Packages.
  4. Знайти потрібний пакет та додати його.

Unity Package Manager

Робота з вихідними джерелами та налагодження

Щоб вихідники підключилися до проекту, необхідно створити Assembly Definition для пакету.

Використання пакетів не обмежує можливості налагодження. Однак під час роботи з пакетами в Unity не можна перейти в IDE на клік на помилку в консолі, якщо помилка сталася в пакеті. Це пов'язано з тим, що Unity не бачить скрипти як окремі файли, оскільки під час використання Assembly Definition вони збираються до бібліотеки та підключаються до проекту. Під час роботи з вихідними джерелами проекту перехід до IDE на кліку доступний.

Скрипт у проекті із підключеним пакетом:

Unity Package Manager
Скрипт із пакета з працюючим брейкпоінтом:

Unity Package Manager

Термінове внесення виправлень у пакети

Додані до проекту пакети Unity відкриті лише для читання, але їх можна редагувати у кеші пакетів. Для цього необхідно:

  1. Перейти до пакету в кеші пакетів.

    Unity Package Manager

  2. Внести потрібні зміни.
  3. Оновити версію у файлі package.json.
  4. Надіслати пакет npm publish --registry *адрес до хранилища пакетов*.
  5. Оновити версію пакета перед виправленою через інтерфейс UPM.

Конфлікти імпорту пакетів

При імпорті пакетів можуть відбутися такі конфлікти GUID'ів:

  1. Пакет – пакет. Якщо при імпорті пакета виявиться, що в вже доданих пакетах є асети з таким же GUID'ом, асети з GUID'ами з імпортованого пакета не додадуться в проект.
  2. Пакет – проект. Якщо при імпорті пакета виявиться, що в проекті є асети з GUID'ами, що збігаються, то асети з пакета не додадуться в проект. Проте ассети, які від них, почнуть використовувати ассети з проекту.

Перенесення ассетів із проекту в пакет

Якщо перенести ассет з проекту в пакет при відкритій Unity, його функціональність збережеться, а посилання в залежних ассетах почнуть використовувати ассет з пакета.

Важливо: під час копіювання ассета з проекту до пакета відбудеться конфлікт «Пакет — проект», описаний у розділі вище.

Можливі вирішення конфліктів

  1. Перепризначення GUID'ів за власними алгоритмами при імпорті всіх ассетів, щоб унеможливити колізії.
  2. Додавання всіх ассетів до одного проекту з наступним поділом на пакети.
  3. Створення бази даних, що містить GUID'и всіх ассетів, та проведення валідації під час відправлення пакетів.

Висновок

UPM — це нове рішення для поширення спільних ресурсів на Unity, яке може стати гідною альтернативою існуючим методам. Рекомендації, описані у статті, виникли з урахуванням реальних кейсів. Сподіваємося, вони стануть вам у пригоді.

Джерело: habr.com

Додати коментар або відгук