Pull to refresh

Использование библиотек в проектах на Unity3D

Reading time4 min
Views22K
Не знаю, как у кого принято, писать всё в одном проекте или кто-нибудь может знает что можно класть сторонние сборки в папку Assembly (как подключаются многие плагины), а кто-то может умеет даже и сам собирать свои библиотеки в папку Assembly, но информации о том кто как делает, и уж каких-то рекомендаций о том как настроить свой проект так, чтобы можно было программировать под Юнити так, как будто вы пишете серьёзное приложение, я не видел.

Суть в том, что обычно приложение разбивается на модули, а каждый модуль кладётся в свою отдельную Сборку. Модуль или библиотека в данном случае не важно, важно что если вам хочется разбить своё приложение на отдельные сборки — то это в принципе достаточно просто сделать, хотя есть и свои подводные камни. Одна из основных проблем — это то что мой подход не будет работать в бесплатной версии Юнити (она не поддерживает загрузку Сборок в рантайме), но и для такого случая есть решение на ссылках файловой системы, о котором расскажу в конце.

Зачем?


Зачем разбивать своё приложение на отдельные модули/библиотеки? Возможно многим не надо объяснять чем хороша группировка кода в библиотеки, но в Юнити можно жить и без них. Зачем делаю это я? Мне удобно использовать одни и те же библиотеки в разных своих проектах, даже самописные. В первую очередь даже самописные. Каждую библиотеку я храню в своём репозитории и если в каком-то из проектов нахожу и исправляю ошибку в библиотеке, то простым коммитом, пушем и пулом из других проектов мои фиксы попадают во все проекты.

Организация проекта


Библиотеки я обычно использую как подмодули (submodule) в репозитории гит. Когда начинаю новый проект, то просто добавляю в пустой репозиторий все подмодули библиотек, которые я буду использовать. Что-то вроде

git init
git submodule add my_rep/systemex.git Libraries/SystemEx


Все библиотеки я всегда кладу в папку Libraries — мне так удобно. Вы можете делать как удобно вам. Каждая библиотека содержит файл проекта с настройками по-умолчанию. Ничего там менять особо не надо, кроме некоторых случаем. Разве что установить версию .net framework в 3.5. А нет, ещё один нюанс — у всех референсов библиотеки нужно установить проперти Copy Local - False. Это избавит от почти всех проблем и странностей после билда.

Далее я создаю в Юнити файлы проектов для студии (я использую visual studio, но подход работает и для monodevelop). Юнити создаёт что-то вроде имя_проекта.sln, имя_проекта-csharp.sln и Assembly-CSharp.csproj, Assembly-CSharp-vs.csproj файлы. Эти файлы она всегда пересоздаёт и их трогать не надо. Что надо сделать — скопировать имя_проекта.sln в имя_проекта-bundle.sln и дальше работать уже с ним.

После чего я создаю в пустую библиотеку классов, которую по традиции называю Code и добавляю её в солюшен. Вот ей уже надо добавить все библиотеки в референсы и выставить им Copy Local - True, хотя он должен стоять по-умолчанию. Второе что надо сделать с этой библиотекой — задать ей Output Path: ..\Assets\Assemblies\ — обычно я создаю эту библиотек в корне проекта, поэтому ..\Assets\ — будет как раз той самой папкой Assets с которой работает Юнити. И всё, собираем библиотеку Code, она выкладывает файлы в Assets\Assemblies\, Юнити видит эти файлы и добавляет референсы в Assembly-CSharp.csproj. Всё должно работать как часы. Единственные минусы — надо два раза жать билд, и навигация по коду из проекта Assembly-CSharp.csproj работать не будет.

После всего этого мой солюшен выглядит примерно так:
image

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

Нюансы


* В своих библиотеках можно использовать UnityEngine.dll — нужно лишь просто добавить её в референсы, но ей обязательно выключить Copy Local иначе она уйдёт в Assemblies и Юнити станет плохо.
* У всех библиотек нужно выключить Copy Local и оставить его только у Code, иначе есть шанс что притянется что-то лишнее. особенно если вы также будете расширять редактор. В своё время я какое-то время помучился с этим, пока нашел причину и решение.
* Расширять редактор можно так же, но надо выкладывать Code.Editor в Output Path: ..\Assets\Editor\Assemblies\
* Юнити не любит и не понимает если одна и та же сборка лежит в нескольких папках.
* Механизм работает только для платных версий. Точнее в бесплатной с ним вроде можно работать, но публиковать такие проекты не получится.

Если хочется бесплатно


В таком случае можно так же использовать гит и структуру репозитория, только по мест придётся руками делать линки файловой системы папок с кодом библиотек в папку Assemblies проекта Юнити. И не надо будет шаманить с файлами проекта, Юнити будет заниматься всем сама. Что-то типа
mklink /J .\Assets\Plugins\MathEx .\Libraries\MathEx\Assets\Plugins\MathEx

В данном случае .\Libraries\MathEx\Assets\Plugins\MathEx папка где лежат .cs файлы.

Спасибо, надеюсь кому-нибудь мои советы пригодятся. Keep your code clean.

upd: Как написал в комментах ZimM, в бесплатной версии тоже всё отлично работает. Так что магия с линками файловой системы в общем то не нужна. Спасибо ему за это.

upd2: Если хочется дебага, и нормальных номеров строк в логах, то надо установить UnityVS, который теперь бесплатный и — самое главное — переключить во всех проектах Target Framework с .NET 3.5 на Unity 3.5 .net Subset Base Class Libraries, или любой другой Unity 3.5 .net
Tags:
Hubs:
+2
Comments6

Articles

Change theme settings