Быстрая обработка данных в LeoECS - это хорошо, но что насчет оповещения других систем о каких-либо событиях? В ECS-подходе это решается довольно просто.
Так как “все есть данные”, то мы можем представить любое событие как блок этих самых данных (компонент в терминах ECS), который в дальнейшем можем удалить после обработки всеми нужными системами. Удалять можно как отдельной системой, которая будет выполняться последней, так и автоматически с использованием специального атрибута.
Пример создания события:
1 | class DamageEvent { |
Если мы подключим обе системы в порядке их описания, то получим постоянно уменьшающийся запас здоровья у юнитов.
В ProcessDamageOnUnitsSystem
-системе видно, что мы удаляем компонент события руками - это вполне нормальное решение, но что если нам нужно обработать данное событие несколькими системами и только после этого удалить? Для этого мы можем вынести удаление в отдельную систему, либо воспользоваться специальным атрибутом [EcsOneFrame]
:
1 | [ ] |
Код идентичный за исключением атрибута на компоненте DamageEvent
и отсутствия явного удаления компонентов этого типа руками. Ядро ECS это сделает автоматически при вызове метода EcsWorld.RemoveOneFrameComponents
:
1 | class EcsStartup : MonoBehaviour { |
Событие может быть не только частью уже существующих сущностей (entity), но и быть независимым от них, например, пользовательский ввод:
1 | [ ] |
По сути данный подход напоминает “шину событий” (EventBus) - события могут обработаться всей последовательностью систем, а так же обработка может быть прекращена любой системой в момент ее выполнения.