|
| 1 | +# LeoECS Lite uGui Bindings - поддержка событий uGui в ECS-мире |
| 2 | +Интеграция событий uGui в ECS-мир. |
| 3 | + |
| 4 | +> Проверено на Unity 2020.3 (зависит от Unity) и содержит asmdef-описания для компиляции в виде отдельных сборок и уменьшения времени рекомпиляции основного проекта. |
| 5 | +
|
| 6 | +> **ВАЖНО!** Зависит от [LeoECS Lite](https://github.com/Leopotam/ecslite) - зависимость должна быть установлена до установки этого модуля. |
| 7 | +> **ВАЖНО!** Зависит от [LeoECS Lite - Расширенные системы](https://github.com/Leopotam/ecslite-extendedsystems) - зависимость должна быть установлена до установки этого модуля. |
| 8 | +
|
| 9 | +* [Установка](#Установка) |
| 10 | + * [В виде unity модуля](#В-виде-unity-модуля) |
| 11 | + * [В виде исходников](#В-виде-исходников) |
| 12 | +* [Классы](#Классы) |
| 13 | + * [EcsUguiEmitter](#EcsUguiEmitter) |
| 14 | + * [EcsUguiCallbackSystem](#EcsUguiCallbackSystem) |
| 15 | + * [Действия](#Действия) |
| 16 | + * [Компоненты](#Компоненты) |
| 17 | +* [Лицензия](#Лицензия) |
| 18 | + |
| 19 | +# Социальные ресурсы |
| 20 | +[](https://discord.gg/5GZVde6) |
| 21 | + |
| 22 | +# Установка |
| 23 | + |
| 24 | +## В виде unity модуля |
| 25 | +Поддерживается установка в виде unity-модуля через git-ссылку в PackageManager или прямое редактирование `Packages/manifest.json`: |
| 26 | +``` |
| 27 | +"com.leopotam.ecslite.unity.ugui": "https://github.com/Leopotam/ecslite-unity-ugui.git", |
| 28 | +``` |
| 29 | +По умолчанию используется последняя релизная версия. Если требуется версия "в разработке" с актуальными изменениями - следует переключиться на ветку `develop`: |
| 30 | +``` |
| 31 | +"com.leopotam.ecslite.unity.ugui": "https://github.com/Leopotam/ecslite-unity-ugui.git#develop", |
| 32 | +``` |
| 33 | + |
| 34 | +## В виде исходников |
| 35 | +Код так же может быть склонирован или получен в виде архива со страницы релизов. |
| 36 | + |
| 37 | +# Классы |
| 38 | + |
| 39 | +## EcsUguiEmitter |
| 40 | +`EcsUiEmitter` является `MonoBehaviour`-классом, отвечающим за генерацию ECS-событий на основе uGui-событий (нажатие, отпускание, перетаскивание и т.п). |
| 41 | +Должен быть размещен на корневом `GameObject`-е UI-иерархии (или хотя бы на корневом `Canvas`-е) и подключен к ECS-инфраструктуре через инспектор: |
| 42 | +```c# |
| 43 | +public class Startup : MonoBehaviour { |
| 44 | + // Поле должно быть проинициализировано в инспекторе средствами редактора Unity. |
| 45 | + [SerializeField] EcsUguiEmitter _uguiEmitter; |
| 46 | + |
| 47 | + EcsSystems _systems; |
| 48 | + |
| 49 | + void Start () { |
| 50 | + _systems = new EcsSystems (new EcsWorld ()); |
| 51 | + _systems |
| 52 | + .Add (new Test1System ()) |
| 53 | + .Add (new Test2System ()) |
| 54 | + // Этот вызов должен быть размещен после всех систем, |
| 55 | + // в которых есть зависимость от uGui-событий. |
| 56 | + .InjectUgui (_uguiEmitter) |
| 57 | + .Init (); |
| 58 | + } |
| 59 | + |
| 60 | + void Update () { |
| 61 | + _systems?.Update (); |
| 62 | + } |
| 63 | + |
| 64 | + void OnDestroy () { |
| 65 | + if (_systems != null) { |
| 66 | + _systems.GetWorld ("ugui-events").Destroy (); |
| 67 | + _systems.GetWorld ().Destroy (); |
| 68 | + _systems = null; |
| 69 | + } |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +public class Test1System : IEcsInitSystem { |
| 74 | + // Это поле будет автоматически инициализировано |
| 75 | + // ссылкой на экземпляр эмиттера на сцене. |
| 76 | + readonly EcsUguiEmitter _ugui = default; |
| 77 | + |
| 78 | + GameObject _btnGo; |
| 79 | + Transform _btnTransform; |
| 80 | + Button _btn; |
| 81 | + |
| 82 | + public void Init (EcsSystems systems) { |
| 83 | + // Получение ссылки на виджет-действие с именем "MyButton". |
| 84 | + _btnGo = _ugui.GetNamedObject ("MyButton"); |
| 85 | + // Чтение Transform-компонента с него. |
| 86 | + _btnTransform = _ugui.GetNamedObject ("MyButton").GetComponent<Transform> (); |
| 87 | + // Чтение Button-компонента с него. |
| 88 | + _btn = _ugui.GetNamedObject ("MyButton").GetComponent<Button> (); |
| 89 | + } |
| 90 | +} |
| 91 | +``` |
| 92 | +Пример выше можно упростить через `[EcsUguiNamedAttribute]`: |
| 93 | +```c# |
| 94 | +public class Test2System : IEcsInitSystem { |
| 95 | + // Все поля будут автоматически заполнены ссылками |
| 96 | + // на соответствующие компоненты с именованного виджета-действия. |
| 97 | + [EcsUguiNamed("MyButton")] GameObject _btnGo; |
| 98 | + [EcsUguiNamed("MyButton")] Transform _btnTransform; |
| 99 | + [EcsUguiNamed("MyButton")] Button _btn; |
| 100 | + |
| 101 | + public void Init (EcsSystems systems) { |
| 102 | + // Все поля инициализированы и могут быть использованы здесь. |
| 103 | + } |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +## EcsUguiCallbackSystem |
| 108 | +Эта система дает возможность напрямую подписываться на uGui-события без дополнительного кода: |
| 109 | +```c# |
| 110 | +public class TestUguiClickEventSystem : EcsUguiCallbackSystem { |
| 111 | + [Preserve] // Этот атрибут необходим для сохранения этого метода для il2cpp. |
| 112 | + [EcsUguiClickEvent] |
| 113 | + void OnAnyClick (in EcsUguiClickEvent evt) { |
| 114 | + Debug.Log ("Im clicked!", evt.Sender); |
| 115 | + } |
| 116 | + |
| 117 | + // Этот метод будет вызван при нажатии на виджет с действием, имеющим имя "exit-button". |
| 118 | + [Preserve] |
| 119 | + [EcsUguiClickEvent("exit-button")] |
| 120 | + void OnExitButtonClicked (in EcsUguiClickEvent evt) { |
| 121 | + Debug.Log ("exit-button clicked!", evt.Sender); |
| 122 | + } |
| 123 | +} |
| 124 | +``` |
| 125 | +Список поддерживаемых атрибутов действий: |
| 126 | +```c# |
| 127 | +[EcsUguiClickEvent] |
| 128 | +[EcsUguiUpEvent] |
| 129 | +[EcsUguiDownEvent] |
| 130 | +[EcsUguiDragStartEvent] |
| 131 | +[EcsUguiDragMoveEvent] |
| 132 | +[EcsUguiDragEndEvent] |
| 133 | +[EcsUguiEnterEvent] |
| 134 | +[EcsUguiExitEvent] |
| 135 | +[EcsUguiScrollViewEvent] |
| 136 | +[EcsUguiSliderChangeEvent] |
| 137 | +[EcsUguiTmpDropdownChangeEvent] |
| 138 | +[EcsUguiTmpInputChangeEvent] |
| 139 | +[EcsUguiTmpInputEndEvent] |
| 140 | +[EcsUguiDropEvent] |
| 141 | +``` |
| 142 | +## Действия |
| 143 | +Действия (классы `xxxAction`) - это `MonoBehaviour`-компоненты, которые слушают события uGui виджетов, ищут `EcsUiEmitter` по иерархии вверх и вызывают генерацию соответствующих событий для ECS-мира. |
| 144 | + |
| 145 | +## Компоненты |
| 146 | +ECS-компоненты, описывающие события: `EcsUguiClickEvent`, `EcsUguiBeginDragEvent`, `EcsUguiEndDragEvent` и т.д. - все они являются стандартными ECS-компонентами и могут быть отфильтрованы с помощью `EcsFilter`: |
| 147 | +```c# |
| 148 | +public class TestUguiClickEventSystem : IEcsInitSystem, IEcsRunSystem { |
| 149 | + EcsPool<EcsUguiClickEvent> _clickEventsPool; |
| 150 | + EcsFilter _clickEvents; |
| 151 | + |
| 152 | + public void Init (EcsSystems systems) { |
| 153 | + var world = systems.GetWorld (); |
| 154 | + _clickEventsPool = world.GetPool<EcsUguiClickEvent> (); |
| 155 | + _clickEvents = world.Filter<EcsUguiClickEvent> ().End (); |
| 156 | + } |
| 157 | + |
| 158 | + public void Run (EcsSystems systems) { |
| 159 | + foreach (var entity in _clickEvents) { |
| 160 | + ref EcsUguiClickEvent data = ref _clickEventsPool.Get (entity); |
| 161 | + Debug.Log ("Im clicked!", data.Sender); |
| 162 | + } |
| 163 | + } |
| 164 | +} |
| 165 | +``` |
| 166 | + |
| 167 | +# Лицензия |
| 168 | +Фреймворк выпускается под двумя лицензиями, [подробности тут](./LICENSE.md). |
| 169 | + |
| 170 | +В случаях лицензирования по условиям MIT-Red не стоит расчитывать на |
| 171 | +персональные консультации или какие-либо гарантии. |
0 commit comments