-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
*.sln | ||
.vscode | ||
.idea | ||
Library | ||
bin | ||
obj | ||
Temp | ||
.DS_Store |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"name": "Leopotam.Ecs.Ui.Editor", | ||
"references": [ | ||
"Leopotam.Ecs.Ui" | ||
], | ||
"includePlatforms": [ | ||
"Editor" | ||
], | ||
"excludePlatforms": [] | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// ---------------------------------------------------------------------------- | ||
// The Proprietary or MIT-Red License | ||
// Copyright (c) 2012-2022 Leopotam <leopotam@yandex.ru> | ||
// ---------------------------------------------------------------------------- | ||
|
||
using UnityEditor; | ||
using UnityEditor.UI; | ||
|
||
namespace Leopotam.Ecs.Ui.Widgets.UnityEditors { | ||
[CustomEditor (typeof (EcsUiNonVisualWidget), false)] | ||
[CanEditMultipleObjects] | ||
sealed class EcsUiNonVisualWidgetInspector : GraphicEditor { | ||
public override void OnInspectorGUI () { | ||
serializedObject.Update (); | ||
EditorGUILayout.PropertyField (m_Script); | ||
RaycastControlsGUI (); | ||
serializedObject.ApplyModifiedProperties (); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
Copyright (c) 2012 - 2022 leopotam@yandex.ru | ||
|
||
Данное программное обеспечение и сопутствующая документация (далее - Продукт) | ||
выпускается на условиях двойного лицензирования - под собственнической/коммерческой | ||
и MIT-Red лицензиями. | ||
|
||
Условия использования под собственнической/коммерческой лицензии обсуждаются | ||
индивидуально, для подробностей следует писать на электронную почту. | ||
|
||
MIT-Red регулируется совокупностью следующих правил, если хотя бы | ||
одно из них невыполнимо - использование Продукта запрещено: | ||
|
||
Если вы за применение opensource программного обеспечения в | ||
военной сфере - вы не можете использовать этот Продукт. | ||
|
||
Если вы испытываете ненависть к русским или поддерживаете | ||
любые нападки на них - вы не можете использовать этот Продукт. | ||
|
||
Данная лицензия разрешает лицам, получившим копию данного Продукта, | ||
безвозмездно использовать Программное обеспечение без ограничений, включая | ||
неограниченное право на использование, копирование, изменение, слияние, | ||
публикацию и распространение копий Продукта. | ||
|
||
Указанное выше уведомление об авторском праве и данные условия должны быть | ||
включены во все копии или значимые части данного Продукта. | ||
|
||
ДАННЫЙ ПРОДУКТ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО | ||
ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ ГАРАНТИИ ТОВАРНОЙ ПРИГОДНОСТИ, | ||
СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ, НО | ||
НЕ ОГРАНИЧИВАЯСЬ ИМИ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ | ||
ОТВЕТСТВЕННОСТИ ПО КАКИМ-ЛИБО ИСКАМ, ЗА УЩЕРБ ИЛИ ПО ИНЫМ ТРЕБОВАНИЯМ, | ||
В ТОМ ЧИСЛЕ, ПРИ ДЕЙСТВИИ КОНТРАКТА, ДЕЛИКТЕ ИЛИ ИНОЙ СИТУАЦИИ, ВОЗНИКШИМ | ||
ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫХ ДЕЙСТВИЙ С ПРОДУКТОМ. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# Интеграция uGui в LeoECS | ||
Интеграция событий uGui в ECS-мир. | ||
|
||
> Проверено на Unity 2020.3 (зависит от Unity) и содержит asmdef-описания для компиляции в виде отдельных сборок и уменьшения времени рекомпиляции основного проекта. | ||
# Содержание | ||
* [Социальные ресурсы](#Социальные-ресурсы) | ||
* [Установка](#Установка) | ||
* [В виде unity модуля](#В-виде-unity-модуля) | ||
* [В виде исходников](#В-виде-исходников) | ||
* [Основные типы](#Основные-типы) | ||
* [EcsUiEmitter](#EcsUiEmitter) | ||
* [Действия](#Действия) | ||
* [Компоненты](#Компоненты) | ||
* [Инициализация](#Инициализация) | ||
* [Лицензия](#Лицензия) | ||
|
||
# Социальные ресурсы | ||
[![discord](https://img.shields.io/discord/404358247621853185.svg?label=enter%20to%20discord%20server&style=for-the-badge&logo=discord)](https://discord.gg/5GZVde6) | ||
|
||
# Установка | ||
|
||
## В виде unity модуля | ||
Поддерживается установка в виде unity-модуля через git-ссылку в PackageManager или прямое редактирование `Packages/manifest.json`: | ||
``` | ||
"com.leopotam.ecs": "https://github.com/Leopotam/ecs-ui.git", | ||
``` | ||
По умолчанию используется последняя релизная версия. Если требуется версия "в разработке" с актуальными изменениями - следует переключиться на ветку `develop`: | ||
``` | ||
"com.leopotam.ecs": "https://github.com/Leopotam/ecs-ui.git#develop", | ||
``` | ||
|
||
## В виде исходников | ||
Код так же может быть склонирован или получен в виде архива со страницы релизов. | ||
|
||
# Основные типы | ||
|
||
## EcsUiEmitter | ||
`EcsUiEmitter` является `MonoBehaviour`-классом, отвечающим за генерацию ECS-событий на основе uGui-событий (нажатие, отпускание, перетаскивание и т.п): | ||
```c# | ||
public class Startup : MonoBehaviour { | ||
// Поле должно быть проинициализировано в инспекторе средствами редактора Unity. | ||
[SerializeField] EcsUiEmitter _uiEmitter; | ||
|
||
EcsSystems _systems; | ||
|
||
void Start () { | ||
var world = new EcsWorld (); | ||
_systems = new EcsSystems (world) | ||
// Дополнительная инициализация... | ||
.Add (new TestSystem ()) | ||
.InjectUi (_uiEmitter); | ||
_systems.Init (); | ||
} | ||
} | ||
|
||
public class TestSystem : IEcsInitSystem { | ||
// Поля с автоматической инъекцией. | ||
EcsUiEmitter _ui; | ||
[EcsUiNamed("MyButton")] GameObject _btnGo; | ||
[EcsUiNamed("MyButton")] Transform _btnTransform; | ||
[EcsUiNamed("MyButton")] Button _btn; | ||
|
||
public void Init () { | ||
// Все поля системы к этому моменту проинициализированы и могут быть использованы: | ||
// _ui - содержит ссылку на EcsUiEmitter. | ||
// _btnGo - содержит ссылку, аналог вызова _ui.GetNamedObject ("MyButton"); | ||
// _btnTransform = содержит ссылку, аналог вызова _ui.GetNamedObject ("MyButton").GetComponent<Transform> (); | ||
// _btn = содержит ссылку, аналог вызова _ui.GetNamedObject ("MyButton").GetComponent<Button> (); | ||
} | ||
} | ||
``` | ||
|
||
> **ВАЖНО!** `EcsUiEmitter` должен быть добавлен к корневому `GameObject`, содержащему виджеты uGui. | ||
> **ВАЖНО!** Не нужно принудительно выполнять инъекцию для `EcsUiEmitter` - вызов метода `EcsSystems.Inject()` делает это автоматически. | ||
## Действия | ||
Действия (классы `xxxAction`) - это `MonoBehaviour`-компоненты, которые слушают события uGui виджетов, ищут `EcsUiEmitter` по иерархии вверх и вызывают генерацию соответствующих событий для ECS-мира. | ||
|
||
## Компоненты | ||
ECS-компоненты, описывающие события: `EcsUiClickEvent`, `EcsUiBeginDragEvent`, `EcsUiEndDragEvent` and others - they can be used as ecs-components with standard filtering through `EcsFilter`: | ||
```c# | ||
public class TestUiClickEventSystem : IEcsRunSystem { | ||
EcsWorld _world; | ||
EcsFilter<EcsUiClickEvent> _clickEvents; | ||
|
||
public void Run () { | ||
foreach (var idx in _clickEvents) { | ||
ref EcsUiClickEvent data = ref _clickEvents.Get1 (idx); | ||
Debug.Log ("Im clicked!", data.Sender); | ||
} | ||
} | ||
} | ||
``` | ||
|
||
# Лицензия | ||
Фреймворк выпускается под двумя лицензиями, [подробности тут](./LICENSE.md). | ||
|
||
В случаях лицензирования по условиям MIT-Red не стоит расчитывать на | ||
персональные консультации или какие-либо гарантии. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// ---------------------------------------------------------------------------- | ||
// The Proprietary or MIT-Red License | ||
// Copyright (c) 2012-2022 Leopotam <leopotam@yandex.ru> | ||
// ---------------------------------------------------------------------------- | ||
|
||
using Leopotam.Ecs.Ui.Systems; | ||
using UnityEngine; | ||
|
||
namespace Leopotam.Ecs.Ui.Actions { | ||
enum EcsUiActionNameRegistrationType { | ||
None, | ||
OnAwake, | ||
OnStart | ||
} | ||
|
||
/// <summary> | ||
/// Base class for ui action. | ||
/// </summary> | ||
public abstract class EcsUiActionBase : MonoBehaviour { | ||
/// <summary> | ||
/// Logical name for filtering widgets. | ||
/// </summary> | ||
[SerializeField] protected string WidgetName = null; | ||
|
||
/// <summary> | ||
/// Ecs entities emitter. | ||
/// </summary> | ||
[SerializeField] protected EcsUiEmitter Emitter = null; | ||
|
||
[SerializeField] EcsUiActionNameRegistrationType _nameRegistrationType = EcsUiActionNameRegistrationType.None; | ||
|
||
[SerializeField] UnityEngine.UI.Selectable _selectable = null; | ||
|
||
void Awake () { | ||
if (_nameRegistrationType == EcsUiActionNameRegistrationType.OnAwake) { | ||
ValidateEmitter (); | ||
RegisterName (true); | ||
} | ||
} | ||
|
||
void Start () { | ||
ValidateEmitter (); | ||
if (_nameRegistrationType == EcsUiActionNameRegistrationType.OnStart) { | ||
RegisterName (true); | ||
} | ||
} | ||
|
||
void OnDestroy () { | ||
RegisterName (false); | ||
} | ||
|
||
void ValidateEmitter () { | ||
if (Emitter == null) { | ||
Emitter = GetComponentInParent<EcsUiEmitter> (); | ||
} | ||
#if DEBUG | ||
if (Emitter == null) { | ||
Debug.LogError ("EcsUiEmitter not found in hierarchy", this); | ||
} | ||
#endif | ||
} | ||
|
||
void RegisterName (bool state) { | ||
// can be destroyed before, cant use fast null check. | ||
if (Emitter) { | ||
Emitter.SetNamedObject (WidgetName, state ? gameObject : null); | ||
} | ||
} | ||
|
||
protected bool IsValidForEvent () { | ||
return Emitter && Emitter.GetWorld().IsAlive () && (_selectable == null || _selectable.interactable); | ||
} | ||
|
||
/// <summary> | ||
/// Helper to add ecs actions from code. | ||
/// </summary> | ||
/// <param name="go">GameObject holder.</param> | ||
/// <param name="widgetName">Optional logical widget name, will be registered with OnStart type.</param> | ||
/// <param name="emitter">Optional emitter. If not provided - will be detected automatically.</param> | ||
public static T AddAction<T> (GameObject go, string widgetName = null, EcsUiEmitter emitter = null) where T : EcsUiActionBase { | ||
var action = go.AddComponent<T> (); | ||
if (widgetName != null) { | ||
action.WidgetName = widgetName; | ||
action._nameRegistrationType = EcsUiActionNameRegistrationType.OnStart; | ||
} | ||
action.Emitter = emitter; | ||
return action; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// ---------------------------------------------------------------------------- | ||
// The Proprietary or MIT-Red License | ||
// Copyright (c) 2012-2022 Leopotam <leopotam@yandex.ru> | ||
// ---------------------------------------------------------------------------- | ||
|
||
using Leopotam.Ecs.Ui.Components; | ||
using UnityEngine; | ||
using UnityEngine.EventSystems; | ||
|
||
namespace Leopotam.Ecs.Ui.Actions { | ||
/// <summary> | ||
/// Ui action for processing OnClick events. | ||
/// </summary> | ||
public sealed class EcsUiClickAction : EcsUiActionBase, IPointerClickHandler { | ||
[Range (1f, 2048f)] | ||
public float DragTreshold = 5f; | ||
|
||
void IPointerClickHandler.OnPointerClick (PointerEventData eventData) { | ||
if ((eventData.pressPosition - eventData.position).sqrMagnitude < DragTreshold * DragTreshold) { | ||
if (IsValidForEvent ()) { | ||
ref var msg = ref Emitter.CreateEntity ().Get<EcsUiClickEvent> (); | ||
msg.WidgetName = WidgetName; | ||
msg.Sender = gameObject; | ||
msg.Position = eventData.position; | ||
msg.Button = eventData.button; | ||
} | ||
} | ||
} | ||
} | ||
} |