Не знаю, как у кого принято, писать всё в одном проекте или кто-нибудь может знает что можно класть сторонние сборки в папку Assembly (как подключаются многие плагины), а кто-то может умеет даже и сам собирать свои библиотеки в папку Assembly, но информации о том кто как делает, и уж каких-то рекомендаций о том как настроить свой проект так, чтобы можно было программировать под Юнити так, как будто вы пишете серьёзное приложение, я не видел.
Суть в том, что обычно приложение разбивается на модули, а каждый модуль кладётся в свою отдельную Сборку. Модуль или библиотека в данном случае не важно, важно что если вам хочется разбить своё приложение на отдельные сборки — то это в принципе достаточно просто сделать, хотя есть и свои подводные камни. Одна из основных проблем — это то что мой подход не будет работать в бесплатной версии Юнити (она не поддерживает загрузку Сборок в рантайме), но и для такого случая есть решение на ссылках файловой системы, о котором расскажу в конце.
Зачем разбивать своё приложение на отдельные модули/библиотеки? Возможно многим не надо объяснять чем хороша группировка кода в библиотеки, но в Юнити можно жить и без них. Зачем делаю это я? Мне удобно использовать одни и те же библиотеки в разных своих проектах, даже самописные. В первую очередь даже самописные. Каждую библиотеку я храню в своём репозитории и если в каком-то из проектов нахожу и исправляю ошибку в библиотеке, то простым коммитом, пушем и пулом из других проектов мои фиксы попадают во все проекты.
Библиотеки я обычно использую как подмодули (
Все библиотеки я всегда кладу в папку
Далее я создаю в Юнити файлы проектов для студии (я использую visual studio, но подход работает и для monodevelop). Юнити создаёт что-то вроде
После чего я создаю в пустую библиотеку классов, которую по традиции называю
После всего этого мой солюшен выглядит примерно так:
В проекте
* В своих библиотеках можно использовать UnityEngine.dll — нужно лишь просто добавить её в референсы, но ей обязательно выключить
* У всех библиотек нужно выключить
* Расширять редактор можно так же, но надо выкладывать
* Юнити не любит и не понимает если одна и та же сборка лежит в нескольких папках.
* Механизм работает только для платных версий. Точнее в бесплатной с ним вроде можно работать, но публиковать такие проекты не получится.
В таком случае можно так же использовать гит и структуру репозитория, только по мест придётся руками делать линки файловой системы папок с кодом библиотек в папку Assemblies проекта Юнити. И не надо будет шаманить с файлами проекта, Юнити будет заниматься всем сама. Что-то типа
В данном случае
Спасибо, надеюсь кому-нибудь мои советы пригодятся. 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
Суть в том, что обычно приложение разбивается на модули, а каждый модуль кладётся в свою отдельную Сборку. Модуль или библиотека в данном случае не важно, важно что если вам хочется разбить своё приложение на отдельные сборки — то это в принципе достаточно просто сделать, хотя есть и свои подводные камни. Одна из основных проблем — это то что мой подход не будет работать в бесплатной версии Юнити (она не поддерживает загрузку Сборок в рантайме), но и для такого случая есть решение на ссылках файловой системы, о котором расскажу в конце.
Зачем?
Зачем разбивать своё приложение на отдельные модули/библиотеки? Возможно многим не надо объяснять чем хороша группировка кода в библиотеки, но в Юнити можно жить и без них. Зачем делаю это я? Мне удобно использовать одни и те же библиотеки в разных своих проектах, даже самописные. В первую очередь даже самописные. Каждую библиотеку я храню в своём репозитории и если в каком-то из проектов нахожу и исправляю ошибку в библиотеке, то простым коммитом, пушем и пулом из других проектов мои фиксы попадают во все проекты.
Организация проекта
Библиотеки я обычно использую как подмодули (
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
работать не будет.После всего этого мой солюшен выглядит примерно так:
В проекте
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