VRMedArena - проект, посвящённый эндовоскулярной хирургии. Проект разрабатывается на движке Unity, под VR.
SCRUM доска проекта.
На текущий момент мы разрабатываем проект на движке Unity версии 6000.3.16f1.
Обязательна установка модулей Android Build Support и его подмодулей OpenJDK и Android SDK & NDK Tools.
Приватный репозиторий доступен по адресу https://github.com/VrMedArena/VRMedArena.git.
Проект поддерживает использование нейросетей. В проекте есть обвязка для работы с Antropic Claude (CLAUDE.md, его скиллы, MCP сервер и т.д.). В файле CLAUDE.md описаны структура и правила проекта.
Мы используем Feature-Based структуру папок в проекте. Весь код проекта находится в папке Assets/_Project; В этой папке папки распределены следующим образом:
| Папка | Назначение | Может ссылаться на |
|---|---|---|
| ./Core | Здесь находятся наиболее общие механики проекта, а также код, работающий с внешними зависимостями (DI,XRHands и т.д.) | - |
| ./Shared | Здесь находятся механизмы для взаимодействия между фичами. В первую очередь это сообщения для MessagePipe либо интерфейсы | Core |
| ./Features/* | Здесь находятся конкретные фичи проекта. Фичи атомарны и не должны ссылаться друг на друга! | Core, Shared |
| ./App | Здесь находятся моки и код для конкретных сцен приложения, которым может понадобиться код со всех фич | Все |
| Наименование | Зачем используем |
|---|---|
| UniTask | Используем вместо IEnumerable, Awaitable и тем более обычных Task. |
| VContainer | Dependency Injection на уровне проекта. |
| MessagePipe + MessagePipe.VContainer | Шина событий на уровне проекта, работает в связке с VContainer. |
| Alchemy | Editor Extension для удобства работы с инспектором и иерархией. |
| Unity MCP | Чистый C# сервер MCP для взаимодействия с LLM. |
| ULogger | Расширенная и настраиваемая система для логирования. |
Для XR взаимодействия мы используем Unity XR Hands + Unity XR Toolkit.
Meta SDK и всё связанное с Meta.
В проекте мы используем стиль K&R. Фигурная скобка остаётся на той же строке, а не переносится на новую.
Правила стиля кода описаны в .editorconfig в корне проекта, VSCode поддерживает его по умолчанию и умеет форматировать текст. При установленном флаге Format On Save форматирование происходит автоматически при сохранении.
Стоит упомянуть следующие правила:
private не пишется вообще, как и другие модификаторы по умолчанию;internal sealed;m_camelCase для приватных полей класса;s_camelCase для приватных статических членов класса;k_PascalCase для приватных констант;camelCase для protected/internal полей класса;PascalCase для public полей и иных членов класса: свойств, методов и т.д.;'I' + PascalCase для интерфейсов;using - только используемые, неиспользуемые вызывают предупреждения;var - используем по возможности вместо явного указания типа;Важно: если в коде есть какие-то значения или логика, требующая решения от врача, обязателен комментарий с тэгом //<SME>
if (!ready) return;, многострочные должны быть обёрнуты в скобки.Также отдельно стоит упомянуть, что именование должно быть на английском языке. Для проверки орфографии стоит использовать Code Spell Checker (CSpell).
Переменные должны именоваться так, чтобы код был читаем.
Псевдокирилицца запрещена.
В проекте активно применяется механизм Nullable. Если сущность может принимать значение null, оно должно быть объявлено таковым, к примеру
Transform? m_t;
В случаях, если нужно сделать поле доступным из инспектора, применяется один из двух вариантов ниже:
[SerializeField] Transform? m_possibleNull;
[SerializeField] Transform m_definitelyNotNull = null!;
Во втором случае требуется в Awake или OnEnable проверить все значения на null и прекратить исполнение кода, если назначенное значение - null. В проекте для этого есть guard помощник:
void OnEnable(){
//RequireField возвращает true, если объект назначен.
//Если объект не назначен - оно выключит объект через enabled = false.
//throwException по умолчанию true, и вызовет исключение, чтобы код не исполнялся дальше.
this.RequireField(m_definitelyNotNull, nameof(m_definitelyNotNull), throwException:true);
}
При созданиие нового asmdef будет автоматически создан csc.rsp, который объявит использование nullable в этом asmdef.
Для сборки билдов на проекте используется система автоматизированная CICD, построенная на Github Actions. Собирать билды вручную нужно только для личных тестов на устройстве, если понадобится.
Каждый коммит, который пушится в гит, проходит тесты и проверки:
Перед тем как иницировать создание билда, стоит убедиться, что тесты из CI прошли успешно, иначе билд не соберётся.
Для того, чтобы инициировать создание билда, следует добавить тэг с версией билда (
dev/x.y.z-wилиrelease/x.y.z) и запушить его на гит.
После того, как тэг отправлен на github, следует подождать, пока билд не cоберётся на сервере. Это занимает до 15 минут.
После сборки, билд будет доступен в папке для Dev или Release билдов.
Для создания Development билда нужно отправить на гит тэг с форматом dev/x.y.z-w, где x.y.z-w - версия билда. Версия x.y.z должна соответствовать предстоящему Release билду. Повышать её не стоит. Нужно инкрементировать w.
Важно: Если
wбыла равна 9 и вам нужна следующая версия, ставьте следующую версию 10, а не повышайтеz
Правильно:
dev/0.0.1-9=>dev/0.0.1-10
Неправильно:
dev/0.0.1-9=>dev/0.0.2-0
Стоит иметь ввиду, что этот билд также будет помечен как Development в редакторе Unity, со всеми вытекающими, вроде доступа к инструментам для дебага, а также расширенному логированию и записи логов на устройство.
Для создания Release билда нужно отправить на гит тэг формата release/x.y.z. Этот билд, помимо всего прочего, будет доступен в самом github в Releases.