Если вы еще не читали ее, взгляните на первую из двух частей. В нем рассказывается о путешествии, которое мы прошли, и о том, почему мы решили попробовать Nuget (Shared Unity Code: The Journey).

Как мы храним пакеты NuGet

Наша серверная команда использует систему упаковки под названием Maven.

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

У нас есть много общего серверного кода, и этот код находится в репозитории Maven, размещенном на сервисе под названием Artifactory. Как оказалось, Artifactory также поддерживает Nuget, поэтому мы смогли использовать его для размещения нашего частного репозитория Nuget!

В целях тестирования вы можете легко создать частное репо на внутреннем сервере, узле AWS или даже просто новую папку на чьем-то компьютере в общей сети — если вы это сделаете, просто убедитесь, что у него есть резервная копия! Все эти варианты описаны в этой статье.

Настройка пакета NuGet

Когда у вас есть место для хранения ваших пакетов, пришло время заставить людей загружать и скачивать их. Вам нужно сначала установить Nuget в вашей системе.

В Windows я бы рекомендовал использовать Шоколадный

В MacOS я бы использовал Homebrew.

Вы также собираетесь сообщить Nuget о своем частном сервере, вы можете сделать это, запустив терминал / командную строку и выполнив следующие команды:

Если вы используете папку на локальном компьютере, вы должны сделать что-то вроде этого:

Если вы настроили имя пользователя, пароль и/или ключ API для своего сервера, вам также необходимо сообщить об этом Nuget:

Использование пакетов

Как только вы это сделаете, вы можете начать загрузку пакетов с вашего частного сервера! Сделать это просто:

Однако это не идеально для проекта с несколькими разработчиками.

У каждого пакета есть версия, а у пакетов есть зависимости от других пакетов, которые также имеют версию. Поэтому мы используем файл конфигурации для каждого проекта, чтобы указать, какие пакеты мы собираемся использовать. Вот пример файла packages.config:

Каждая запись в этом файле указывает имя пакета, номер версии и цель (версия платформы .Net). Все справочные материалы по конфигурационному файлу вы можете найти здесь. Когда у нас есть файл packages.config, мы можем использовать его для установки наших пакетов:

Это проверит каждый пакет в вашем конфигурационном файле и загрузит его на ваш компьютер.

Выпуск пакетов

Чтобы выпустить пакет, вы должны создать файл Nuspec. Этот файл будет определять всю информацию о вашем пакете, включая:

  • Имя пакета
  • Разработчик
  • URL-адрес
  • Версия пакета
  • Зависимости
  • Файлы

Очень важно поддерживать этот файл в актуальном состоянии. Если вы измените зависимость или обновите одну из зависимостей до более новой версии, обновите файл Nuspec!

Файл Nuspec на самом деле является просто еще одним XML-документом, вот пример одного из наших:

Как видите, там довольно много информации, но как только вы настроите этот файл, он не сильно изменится. Для получения подробной информации о файлах Nuspec вы можете перейти на страницу справки. Итак, теперь у вас настроен проект, он собран, тесты пройдены, и у вас есть файл Nuspec, готовый к работе. Вернитесь в терминал и выполните следующие команды:

Первая команда упакует все файлы в файл nupkg (который на самом деле является просто файлом .zip, вы можете изменить расширение на .zip и разархивировать его, чтобы увидеть, что внутри), а вторая отправит его в ваш репозиторий.

Теперь люди могут использовать ваш пакет NuGet!

На самом деле мы создаем и выпускаем все наши модули через Jenkins.

Полный справочник по интерфейсу командной строки Nuget можно найти здесь.

Несколько команд, несколько версий Unity

Возможно, вы заметили, что мы захватываем поле target, чтобы распространять разные библиотеки DLL, скомпилированные для разных версий Unity, в одном пакете. Это довольно нетрадиционно, и мы только недавно начали пробовать, но, похоже, пока все работает нормально.

Это означает, что один пакет может содержать DLL, скомпилированную для Unity 5.6 и Unity 2017, но с помощью поля target мы указываем, что наша игра заинтересована только в DLL Unity 2017.

Это позволяет нам легко поддерживать несколько команд с одними и теми же общими модулями.

Создание нескольких DLL

Чтобы собрать наши модули для разных версий Unity, мы изменяем файл проекта C#, чтобы он имел несколько конфигураций — по одной для каждой версии Unity, с которой мы собираемся.

Затем каждой конфигурации назначаются необходимые определения препроцессора (например, UNITY_5_6_OR_NEWER, UNITY_2017_1_OR_NEWER и т. д.). И каждая конфигурация связана с правильными библиотеками Unity.

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

Единство и NuGet

Когда вы создаете префабы в Unity и назначаете пользовательский скрипт этому префабу, GUID этого скрипта сохраняется внутри префаба. Поэтому, если GUID скрипта когда-либо изменится, ваш префаб потеряет ссылку на скрипт.

Так что в следующий раз, когда вы выпустите свой пакет и будете очень рады, что все его обновят, они это сделают, и все их префабы сломаются. Почему?

Nuget помещает номер версии в имя библиотеки DLL (например, SpaceApe.PerformanceTesting.1.0.0.dll)

Когда вы обновляете свой пакет, номер версии изменится (что также изменит имя файла!)

Unity вычисляет GUID скрипта в DLL, принимая

  • имя DLL
  • название скрипта
  • А затем смешать их вместе

Поэтому, когда мы устанавливаем пакеты, мы используем специальную опцию –excludeversion, которая не помещает номер версии пакета в DLL и не удаляет метафайл DLL, например:

Где мы сейчас

Так что в нынешнем виде у нас все работает очень хорошо.

  • Мы можем делиться кодом между командами
  • Мы можем поддерживать несколько версий Unity
  • Наш код поставляется со все большим количеством тестов
  • Многие наши модули хорошо документированы, и документация автоматически обновляется при каждом выпуске.

Все это приводит к одному: наши команды разработчиков могут заниматься самым важным — созданием определяющего жанр хита.