### Наш контекст:
Я разрабатываю 3D-игру в жанре RTS. Использую Unity (код на C#).
Игра поделена на Core и View части.
При разработке Core-части используются подходы:
- Engine-Agnostic
- Самописный ECS (Entity Component System). То есть, в том числе, не используется DOTS от Unity.
View-часть может иметь зависимости от Core-части, но не наоборот.
В игре будет огромное количество сущностей, компонентов, систем. Поэтому решение должно быть оптимальным по производительности
### Наша задача:
- Разработать архитектуру
- Взаимодействия Core и View части с учетом контекста.
- View-части
- Разработать механизм, который позволяет узнавать об изменениях ECS-компонента через отложенную реактивность.
### Учесть:
- View-часть уже имеет свою архитектуру из коробки от Unity (архитектурный паттерн Entity-Component**)**
### Какие есть потребности к архитектуре:
- При перемещении предмета из нефтяной вышки в инвентарь, View-часть оповещает Core об изменениях.
- Core перемещает humvee через position и rotation. View нужно это отобразить.
- Core создает на карте humvee, View нужно создать на карте модель транспорта.
<br>
<br>
Как можно реализовать взаимодействие Core - View
Через event-компоненты
- View получает все данные через ECS-компоненты.
- В одном кадре сначала выполняется Core, а потом View (последовательность настраивается в настройках Unity-редактора). Благодаря чему, View будет реагировать моментально на изменения данных в Core
- Если View нужно передать данные в Core, то View делает это через ECS-компоненты.
Через Мост
Данные, которые либо покадрово меняются и могут не меняться долгое время и при этом «слушателю» важно также покадрового следить за обновлениями (например, движение транспорта по карте. поля position/rotation), лучше передавать во View через события и его производные, а не через ECS-компоненты.
- Почему лучше так? Слишком много телодвижений требуется, так как мы генерируем события каждый кадр, чтобы менять данные. Получается, «пушкой по воробьям»
- Что подразумевается под событиями: Event, делегаты, интерфейсы
- Core меняет данные в ECS-компоненте, а View подхватывает изменения через события моментально.
<br>
Архитектуру для View не сделать никак, потому что у нее уже есть своя архитектура. Остается только писать код под данную архитектуру.
Оповещение об изменениях
<br>
### Хранение данных
Очень удобно работать с данными в Unity, когда они все отображаются в инспекторе (моя механика Mono).
- Также, удобно, что можно на сцену бросить префаб и он будет сразу работать.
Однако, есть некоторые минусы:
- Данные в Unity-компонентах часто слетали при сбоях Unity-редактора.
- Муторно постоянно создавать мосты для новых поле/ECS-компонентов
- Данные, которые по идее должны храниться в Core, почему-то хранятся во View
- При разработке серверной части игры, придется переписать хранение данных.
Механику Mono можно оставить для тех случаев, когда важно всегда передавать во View значения полей для его моментальной реакции. А также поменять механику. Сделать так, чтобы данные хранились в Core, а View лишь подтягивал их.
Можно сохранить возможность «бросания» на сцену префабов, создав специальный unity-компонент, который будет создавать Entity и компонентами в момент запуска игры прям в префабе (в ю-компоненте)
### Создание gameobject с Mono-компонентами
Если Core хочет создать Entity, у которого есть «физическая оболочка» в 3D-мире, то как должна работать механика.
Что нам нужно от View
- Добавление определенного префаба на сцену (на сцене появится gameobject
- К этому gameobject нужно добавить Mono, который позволит через мост View-части копировать значение некоторых полей transform (position, rotation и так далее)
Что мы можем сделать:
~~К entity привязываем ECS-маркер-компонент, который говорит, что «мне нужно, чтобы View создало префаб для этого entity»~~
Можно просто создать интерфейс, который будет использовать Core, а имплементирован будет View-частью. В интерфейсе будут методы, которые позволят создать префаб и привязать необходимые компоненты-мосты.
##### Изменение меша для 3д-модели при нанесении критического урона или полного уничтожения.
Создать единый monobehavior-скрипт-менеджер, который будет обрабатывать все эвент-компоненты, связанные с обновлением меша.
<br>
<br>
Потребность в создании сконфигурированного Entity есть не только у Core, но и у View части.
Если View будет обращаться к Core для создания, то Core не может просто так отдать ссылку на gameobject
Core должен в любом случае этим заниматься созданием, так как он же конфигурирует сущности.
<br>
##### Возможность просто закинуть префаб на сцену
EntityMono2 будет вызывать EntityConfigurator. И конфигуратор уже добавит сам остальные Mono-компоненты
Остальные Mono-компоненты нельзя будет добавлять напрямую. Они будут работать, только если их добавить через код.
<br>
<br>
Можно создавать один компонент на несколько систем для простоты разработки, при условии, что эти системы предназначены для работы друг с другом. Если же, эти системы должны работать с другими системами, то они должны иметь свои компоненты, чтобы быть независимыми друг от друга. ( просто мысль записал, возможно она неправильная, нужно будет обдумать на свежую голову)