Всем привет. Давненько я ничего не писал технического на DTF (хотя есть вопрос - на кой черт я вообще это делаю). В этот раз я решил немного покопать архитектуру проектов при разработке игр на Unity и пройтись по самым часто встречаемым мной подходам. Ну и конечно же рассказать, зачем я такой мазохист и пришел к любимому мной HMVС (HMVP).
Привожу проекты к виду примерно MVVM, максимально сохраняю компонентную систему. Можно делать с DI, можно без. Тут скорее зависит от способности команды полноценно использовать DI - для Unity проектов это не столь важно как в вебе. Zenject не советую использовать без опыта, требуется много времени на изучение, очень легко скатиться к лапше, божественным структурам, и вообще собрать все грабли. Поглядывал на другие вещи, что попроще, но уже забыл названия)
View - компоненты отображения, коим может быть и стандартный Image и какая-нить панелька с ресурсами. Иерархия с другими View(может содеражать в себе), но у каждого объекта только одна связь с VM. Отображение данных полученных от VM без изменения. Ограничивать можно через интерфейс.
VM - это модель UI, по сути тот же Presenter и управление логикой как в Model, но по отношению к UI. К примеру, это окна, попапы, ну или целый UI магазина. Иерархичен по отношению к другим VM, взаимодействует с другими частями, вызывает методы в Model, но не имеет доступа к его данным(только управление). Передаёт данные в View, получает. Иногда напрямую, иногда как посредник передаёт данные во View. Здесь так же разделение между данными в Model и передаваемыми во View - для Prediction, уборки сетевой задержки и т.п.
Model - логика игры. Тут важно - не стоит пытаться делать все объекты не MonoBehaviour. Если объект на сцене - часть непосредственной логики игры, в т.ч. физики, то так и должно быть. Если надо ту же логику повторить на сервере - тащите как есть и делайте свою реализацию MB на сервере, либо делите через partial(лучше), ну или наследованием и контенерами данных(хуже). Это так же позволяет использовать Photon и другую логику непосредственно игрового процесса на сервере(т.е. с апдейтами или их имитацией).
Так ещё несколько отличительных, часто:
1) нужен Update - это или View или VM.
2) нужен FixedUpdate - Model.
3) Model в любой реализации должен компилится без View и VM. В идеале, Model в новых версиях отделять в отдельную сборку(-и).
Касательно загрузки. Управление загрузкой осуществляется из M и VM. Тут только иногда требуются какие-то общее ожидание загрузки и для M, и для VM, делая эту загрузку независимо друг от друга(для Model обычно ожидания ответа от сервера логики, а для VM сканиявание и загрузка ассетов). C использованием Task это наконец-то получается организовать правильно и легко читаемо, без костылей типа сервис-локатора, синглтонов и т.п..
Хороший пример. MVVM часто используется на играх где много UI.
Можно посмотреть на пример вашей реализации данного подхода. Будет очень полезно для новичков типо меня :)
Объясните как андроид девелоперу. Что вообще в данном случае выполняет вью? Предположим, в модели есть обработка физики, контроллер ввода пользователя, запуск анимаций и т.д. Т.е. всё, что влияет на непосредственно на ход игры. Что делает View? Только UI? т.е. для большинства геймплейных объектов VVM не нужны? Или View и VM как раз и выполняют обработку ввода и запуск анимаций? А то куда ни зайди - везде срачи по поводу того, нужны ли MV* паттерны в юнити