- PVSM.RU - https://www.pvsm.ru -

Unity Package Manager

Unity — платформа, которая существует довольно давно и постоянно развивается. Однако, работая в ней с несколькими проектами одновременно, все еще можно столкнуться со сложностями в использовании общих исходников (.cs), библиотек (.dll) и остальных ассетов (изображения, звуки, модели, префабы). В этой статье мы расскажем о нашем опыте работы с нативным решением такой проблемы для Unity.

Unity Package Manager - 1

Методы распространения общих ресурсов

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

1. Дублирование — «руками» дублируем ресурсы между проектами.

Плюсы:

  • Подходит для всех видов ресурсов.
  • Нет проблем с зависимостями.
  • Нет проблем с GUID’ами ассетов.

Минусы:

  • Гигантские репозитории.
  • Нет возможности версионирования.
  • Сложность отслеживания изменений в общих ресурсах.
  • Сложность обновления общих ресурсов.

2. Git submodules [1] — распространение общих ресурсов через внешние подмодули.

Плюсы:

  • Можно работать с исходниками.
  • Можно распространять ассеты.
  • Нет проблем с зависимостями.

Минусы:

  • Необходим навык работы с 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 - 2

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

Пакеты не попадают в исходники проекта (директорию Assets). Они находятся в отдельной директории %projectFolder%/Library/PackageCache и никак на проект не влияют, их единственное упоминание в исходниках — в файле packages/manifest.json.

Unity Package Manager - 3

Пакеты в файловой системе проекта

Источники пакетов

UPM может использовать несколько источников пакетов:

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

Плюсы:

  • Скорость реализации.
  • Не требует сторонних инструментов.

Минусы:

  • Сложность версионирования.
  • Необходим общий доступ к файловой системе для всех, кто работает с проектом.

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

Плюсы:

  • Нужен только Git-репозиторий.

Минусы:

  • Нельзя переключаться между версиями через окно UPM.
  • Работает не со всеми Git-репозиториями.

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

Плюсы:

  • Полностью поддерживает функционал UPM и используется для распространения официальных пакетов Unity.

Минусы:

  • В настоящее время игнорирует все строковые версии пакетов, кроме «-preview».

Ниже мы рассмотрим реализацию UPM + npm. Эта связка удобна, поскольку позволяет работать с любыми видами ресурсов и управлять версиями пакетов, а также полностью поддерживает нативный интерфейс UPM.

В качестве npm-репозитория можно использовать Verdaccio [2]. К нему есть подробная документация [3], и для его запуска потребуется буквально пара команд.

Настройка окружения

Для начала нужно установить node.js [4].

Создание пакета

Чтобы создать пакет, необходимо поместить файл 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 - 4

Работа с исходниками и отладка

Чтобы исходники подключились к проекту, необходимо создать Assembly Definition [5] для пакета.

Использование пакетов не ограничивает возможности для отладки. Однако при работе с пакетами в Unity нельзя перейти в IDE по клику на ошибку в консоли, если ошибка произошла в пакете. Это связано с тем, что Unity не видит скрипты как отдельные файлы, поскольку при использовании Assembly Definition они собираются в библиотеку и подключаются к проекту. При работе с исходниками из проекта переход в IDE по клику доступен.

Скрипт в проекте с подключенным пакетом:

Unity Package Manager - 5

Скрипт из пакета с работающим брейкпоинтом:

Unity Package Manager - 6

Срочное внесение исправлений в пакеты

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

  1. Перейти в пакет в кэше пакетов.
    Unity Package Manager - 7

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

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

При импорте пакетов могут произойти следующие конфликты GUID’ов:

  1. Пакет — пакет. Если при импорте пакета обнаружится, что в уже добавленных пакетах есть ассеты с таким же GUID’ом, ассеты с совпавшими GUID’ами из импортируемого пакета не добавятся в проект.
  2. Пакет — проект. Если при импорте пакета обнаружится, что в проекте есть ассеты с совпадающими GUID’ами, то ассеты из пакета не добавятся в проект. Однако ассеты, зависящие от них, начнут использовать ассеты из проекта.

Перенос ассетов из проекта в пакет

Если перенести ассет из проекта в пакет при открытой Unity, то его функциональность сохранится, а ссылки в зависимых ассетах начнут использовать ассет из пакета.

Важно: при копировании ассета из проекта в пакет произойдет конфликт «Пакет — проект», описанный в разделе выше.

Возможные решения конфликтов

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

Заключение

UPM — новое решение для распространения общих ресурсов на Unity, которое может стать достойной альтернативой существующим методам. Рекомендации, описанные в статье, возникли на основе реальных кейсов. Надеемся, они вам пригодятся.

Автор: Plarium

Источник [6]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/razrabotka/312720

Ссылки в тексте:

[1] Git submodules: https://git-scm.com/book/ru/v1/%D0%98%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B-Git-%D0%9F%D0%BE%D0%B4%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B8

[2] Verdaccio: https://verdaccio.org/

[3] документация: https://verdaccio.org/docs/en/what-is-verdaccio.html

[4] node.js: https://nodejs.org/en/

[5] Assembly Definition: https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html

[6] Источник: https://habr.com/ru/post/445432/?utm_campaign=445432