mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2026-04-21 20:15:56 +08:00
remove IEntityTemplate / update readme
This commit is contained in:
parent
dc0aae1c67
commit
9aa4d21e79
86
README-RU.md
86
README-RU.md
@ -48,10 +48,10 @@
|
||||
# Оглавление
|
||||
- [Установка](#установка)
|
||||
- [Debug](#debug)
|
||||
- [Debug Модуль](#debug-модуль)
|
||||
- [Debug Сервис](#debug-сервис)
|
||||
- [Debug Модуль](#debug-модуль)
|
||||
- [Визуальная отладка](#визуальная-отладка)
|
||||
- [Шаблон Сущности](#шаблон-сущности)
|
||||
- [Шаблоны](#шаблоны)
|
||||
- [Связь с GameObject](#связь-с-gameobject)
|
||||
- [World Provider](#world-provider)
|
||||
- [Шаблон Пайплайна](#шаблон-пайплайна)
|
||||
@ -85,21 +85,8 @@ https://github.com/DCFApixels/DragonECS-Unity.git
|
||||
</br>
|
||||
|
||||
# Debug
|
||||
## Debug Модуль
|
||||
Подключение модуля отладки в Unity.
|
||||
```c#
|
||||
EcsDefaultWorld _world = new EcsDefaultWorld();
|
||||
EcsEventWorld _eventWorld = new EcsDefaultWorld();
|
||||
|
||||
_pipeline = EcsPipeline.New()
|
||||
//...
|
||||
// Подключение и инициализация отладки для миров _world и _eventWorld
|
||||
.AddUnityDebug(_world, _eventWorld)
|
||||
//...
|
||||
.BuildAndInit();
|
||||
```
|
||||
## Debug Сервис
|
||||
`UnityDebugService`- реализация [Debug-сервиса для `EcsDebug`](https://github.com/DCFApixels/DragonECS/blob/main/README-RU.md#ecsdebug). В редакторе по умолчанию автоматически инициализируется и связывает `EcsDebug.Print` с консолью Unity, `EcsProfilerMarker` c профайлером и т.д.
|
||||
`UnityDebugService` - реализация [Debug-сервиса для `EcsDebug`](https://github.com/DCFApixels/DragonECS/blob/main/README-RU.md#ecsdebug). В редакторе он инициализируется автоматически и обеспечивает интеграцию: например, вызовы `EcsDebug.Print` направляются в консоль Unity, а `EcsProfilerMarker` подключается к встроенному профайлеру и т.д.
|
||||
```c#
|
||||
//Ручная активация.
|
||||
UnityDebugService.Activate();
|
||||
@ -115,8 +102,19 @@ someMarker.End();
|
||||
//Остановка игрового режима.
|
||||
EcsDebug.Break();
|
||||
```
|
||||
|
||||
## Визуальная отладка
|
||||
Выполнена в виде специальных объектов-мониторов в которых отображается состояние разных аспектов фреймворка. Найти эти мониторы можно в Play Mode в разделе `DontDestroyOnLoad`.
|
||||
|
||||
Выполнена в виде специальных объектов-мониторов в которых отображается состояние разных частей фреймворка. Найти эти мониторы можно в `Play Mode` в разделе `DontDestroyOnLoad`.
|
||||
|
||||
```c#
|
||||
_pipeline = EcsPipeline.New()
|
||||
//...
|
||||
// Инициализация отладки для пайплайна и миров
|
||||
.AddUnityDebug(_world, _eventWorld)
|
||||
//...
|
||||
.BuildAndInit();
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/DCFApixels/DragonECS-Unity/assets/99481254/54e3f6d1-13c4-4226-a983-c672a29d33bb">
|
||||
@ -143,7 +141,7 @@ EcsDebug.Break();
|
||||
-----
|
||||
|
||||
* ### `WorldMonitor`
|
||||
Показывает состояние `EcsWorld`. на каждый казанный мир создается отдельный монитор.
|
||||
Показывает состояние `EcsWorld`. на каждый мир, переданный в `AddUnityDebug(...)`, создается отдельный монитор.
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/DCFApixels/DragonECS-Unity/assets/99481254/7b6455fc-9211-425c-b0b8-288077e61543">
|
||||
@ -162,26 +160,11 @@ EcsDebug.Break();
|
||||
|
||||
</br>
|
||||
|
||||
# Шаблон Сущности
|
||||
Настраиваемый набор компонентов которые можно применить к сущностям. Шаблоны должны реализовывать интерфейс `ITemplateNode`.
|
||||
```c#
|
||||
ITemplateNode someTemplate = /*...*/;
|
||||
//...
|
||||
foreach (var e in _world.Where(out Aspect a))
|
||||
{
|
||||
// Применение шаблона сущности.
|
||||
someTemplate.Apply(e, _world.id);
|
||||
}
|
||||
```
|
||||
```c#
|
||||
// Применение шаблона сразу при создании сущности.
|
||||
int e = _world.NewEntity(someTemplate);
|
||||
```
|
||||
По умолчанию расширение содержит 2 вида шаблонов: `ScriptableEntityTemplate`, `MonoEntityTemplate`.
|
||||
# Шаблоны
|
||||
Интеграция содержит шаблоны расширяющие `ITemplateNode`, предназначенные для настройки сущностей из редактора.
|
||||
|
||||
## ScriptableEntityTemplate
|
||||
Хранится как отдельный ассет. Наследуется от `ScriptableObject`.
|
||||
Действия чтобы создать `ScriptableEntityTemplate` ассет:
|
||||
|
||||
<details>
|
||||
<summary>Создать ассет: Asset > Create > DragonECS > ScriptableEntityTemplate.</summary>
|
||||
@ -222,8 +205,9 @@ int e = _world.NewEntity(someTemplate);
|
||||
|
||||
## Шаблон компонента
|
||||
|
||||
Чтобы компонент попал в меню `Add Component` требуется шаблон. Шаблоны компонента это типы реализующие `IComponentTemplate`.
|
||||
|
||||
### Реализация
|
||||
Чтобы компонент попал в меню `Add Component` нужно реализовать шаблон компонента. Шаблоны компонента это типы реализующие `IComponentTemplate`.
|
||||
|
||||
* Упрощенная реализация:
|
||||
```c#
|
||||
@ -243,6 +227,8 @@ class SomeTagComponentTemplate : TagComponentTemplate<SomeComponent> { }
|
||||
<details>
|
||||
<summary>* Полная реализация:</summary>
|
||||
|
||||
Если не подходят `ComponentTemplate<T>` или `TagComponentTemplate<T>`, можно напрямую реализовать интерфейс `IComponentTemplate`. Например это может пригодиться для работы в связке с кастомной реализацией пула. В большинстве случаев достаточно упрощенной.
|
||||
|
||||
```c#
|
||||
[Serializable]
|
||||
struct SomeComponent : IEcsComponent { /* ... */ }
|
||||
@ -251,6 +237,7 @@ class SomeComponentTemplate : IComponentTemplate
|
||||
[SerializeField]
|
||||
protected SomeComponent component;
|
||||
public Type Type { get { return typeof(SomeComponent); } }
|
||||
public bool IsUnique { get { return true; } }
|
||||
public void Apply(int worldID, int entityID)
|
||||
{
|
||||
EcsWorld.GetPoolInstance<EcsPool<SomeComponent>>(worldID).TryAddOrGet(entityID) = component;
|
||||
@ -268,28 +255,37 @@ class SomeComponentTemplate : IComponentTemplate
|
||||
### Кастомизация отображения типов
|
||||
В раскрывающемся при нажатии `Add Component` меню выбора компонента поддерживается иерархическое группирование. Производится группирование на основе мета-атрибута `[MetaGroup]`.
|
||||
|
||||
Компоненты в инспекторе по умолчанию отображаются окрашенными в случайный цвет сгенерированный на основе имени компонента, выбрать другой режим окраски можно в [окне настроек](#окно-настроек) фреймворка. Задать конкретный цвет можно при помощи мета-атрибута `[MetaColor]`.
|
||||
Компоненты в инспекторе по умолчанию отображаются со случайным цветом, зависящим от его имени, выбрать другой режим окраски можно в [окне настроек](#окно-настроек) фреймворка. Задать конкретный цвет можно при помощи мета-атрибута `[MetaColor]`.
|
||||
|
||||
Если редактор смог автоматически определить связанный с компонентом скрипт, то слева от крестика удаления компонента будет иконка файла. Клик по иконке выделит файл скрипта в папке проекта, двойной клик откроет скрип для редактирования. Связанный файл ищется по сопоставлению имени типа и имени файла скрипта.
|
||||
Если интеграции удается найти соответствующий скрипт (по совпадению имени типа и файла, либо при наличии `[MetaID]`), рядом с крестиком удаления появляется иконка файла — клик выделяет скрипт в проекте, двойной клик открывает его.
|
||||
|
||||
Если у компонента есть мета-атрибут `[MetaDescription]`, то слева от крестика удаления компонента будет иконка подсказки, при наведении курсора покажется информация из `[MetaDescription]`.
|
||||
При наличии атрибута `[MetaDescription]` показывается иконка подсказки с текстом из него.
|
||||
|
||||
</br>
|
||||
|
||||
### Применение шаблонов компонентов вне стандартных шаблонов сущностей
|
||||
При необходимости создания пользовательского шаблона, шаблоны компонентов поддерживают отображение вне стандартных `MonoEntityTemplate` и `ScriptableEntityTemplate`.
|
||||
Шаблоны компонентов можно использовать не только внутри стандартных `MonoEntityTemplate` и `ScriptableEntityTemplate`, но и в любых пользовательских классах. Для этого предусмотрены два способа:
|
||||
|
||||
Атрибут `[ComponentTemplateReference]`:
|
||||
```c#
|
||||
// ComponentTemplateReference добавляет кнопку выбора доступной реализации IComponentTemplate
|
||||
// Добавляет кнопку выбора доступной реализации IComponentTemplate
|
||||
// и отображает шаблон компонента аналогично компонентам в MonoEntityTemplate или ScriptableEntityTemplate.
|
||||
[SerializeReference, ComponentTemplateReference]
|
||||
private IComponentTempalte _someComponent1;
|
||||
private IComponentTemplate _someComponent1;
|
||||
```
|
||||
|
||||
// Обертка над IComponentTempalte, которая работает аналогично примеру с атрибутом ComponentTemplateReference.
|
||||
Обертка `ComponentTemplateProperty`:
|
||||
```c#
|
||||
// Обертка над IComponentTemplate, аналогично примеру с атрибутом ComponentTemplateReference.
|
||||
private ComponentTemplateProperty _someComponent2;
|
||||
```
|
||||
|
||||
// Все это работает и для массивов.
|
||||
Оба подхода работают и для массивов:
|
||||
```c#
|
||||
[SerializeReference, ComponentTemplateReference]
|
||||
private IComponentTempalte[] _components;
|
||||
private IComponentTemplate[] _components;
|
||||
// или
|
||||
private ComponentTemplateProperty[] _components;
|
||||
```
|
||||
|
||||
</br>
|
||||
|
||||
@ -113,9 +113,9 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
get { return _monoTemplates; }
|
||||
}
|
||||
public IEnumerable<IEntityTemplate> AllTemplates
|
||||
public IEnumerable<ITemplateNode> AllTemplates
|
||||
{
|
||||
get { return ((IEnumerable<IEntityTemplate>)_scriptableTemplates).Concat(_monoTemplates); }
|
||||
get { return ((IEnumerable<ITemplateNode>)_scriptableTemplates).Concat(_monoTemplates); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@ -84,6 +84,12 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
public static class GameObjectRefExt
|
||||
{
|
||||
public static entlong NewEntityWithGameObject(this EcsWorld world, ITemplateNode template, string name = "Entity", GameObjectIcon icon = GameObjectIcon.NONE)
|
||||
{
|
||||
entlong e = world.NewEntityWithGameObject(name, icon);
|
||||
template.Apply(world.ID, e.ID);
|
||||
return e;
|
||||
}
|
||||
public static entlong NewEntityWithGameObject(this EcsWorld self, string name = "Entity", GameObjectIcon icon = GameObjectIcon.NONE)
|
||||
{
|
||||
entlong result = self.NewEntityLong();
|
||||
|
||||
@ -33,7 +33,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
private static ComponentTemplatesDropDown _componentDropDown;
|
||||
|
||||
#region Properties
|
||||
private float SingleLineWithPadding => OneLineHeight + Padding * 4f;
|
||||
private float Padding => Spacing;
|
||||
protected override bool IsStaticInit => _componentDropDown != null;
|
||||
#endregion
|
||||
|
||||
@ -7,7 +7,7 @@ using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
internal abstract class EntityTemplateEditorBase : ExtendedEditor<IEntityTemplateInternal>
|
||||
internal abstract class EntityTemplateEditorBase : ExtendedEditor<ITemplateNode>
|
||||
{
|
||||
private ComponentTemplatesDropDown _componentDropDown;
|
||||
|
||||
@ -17,15 +17,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
|
||||
protected abstract bool IsSO { get; }
|
||||
|
||||
//public virtual bool IsStaticData { get { return false; } }
|
||||
|
||||
#region Init
|
||||
protected override bool IsInit { get { return _componentDropDown != null; } }
|
||||
protected override void OnInit()
|
||||
{
|
||||
_componentDropDown = new ComponentTemplatesDropDown();
|
||||
|
||||
_componentsProp = serializedObject.FindProperty(Target.ComponentsPropertyName);
|
||||
_componentsProp = serializedObject.FindProperty("_componentTemplates");
|
||||
|
||||
_reorderableComponentsList = new ReorderableList(serializedObject, _componentsProp, true, false, false, false);
|
||||
_reorderableComponentsList.onAddCallback += OnReorderableComponentsListAdd;
|
||||
@ -142,19 +140,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
|
||||
#endregion
|
||||
|
||||
#region Add/Remove
|
||||
private void OnRemoveComponentAt(int index)
|
||||
{
|
||||
if (this.target is IEntityTemplateInternal target)
|
||||
{
|
||||
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
|
||||
componentsProp.DeleteArrayElementAtIndex(index);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(this.target);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected override void DrawCustom()
|
||||
{
|
||||
Init();
|
||||
@ -204,7 +189,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetTransperentBlackBackgrounStyle()))
|
||||
{
|
||||
DrawTop(Target, _componentsProp);
|
||||
DrawTop(_componentsProp);
|
||||
_reorderableComponentsList.DoLayoutList();
|
||||
}
|
||||
}
|
||||
@ -214,7 +199,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
}
|
||||
}
|
||||
}
|
||||
private void DrawTop(IEntityTemplateInternal target, SerializedProperty componentsProp)
|
||||
private void DrawTop(SerializedProperty componentsProp)
|
||||
{
|
||||
GUILayout.Space(2f);
|
||||
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
#if DISABLE_DEBUG
|
||||
#undef DEBUG
|
||||
#endif
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface IEntityTemplate : ITemplateNode { }
|
||||
|
||||
public static class ITemplateNodeExtensions
|
||||
{
|
||||
public static entlong NewEntityWithGameObject(this EcsWorld world, ITemplateNode template, string name = "Entity", GameObjectIcon icon = GameObjectIcon.NONE)
|
||||
{
|
||||
entlong e = world.NewEntityWithGameObject(name, icon);
|
||||
template.Apply(world.ID, e.ID);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
internal interface IEntityTemplateInternal : IEntityTemplate
|
||||
{
|
||||
string ComponentsPropertyName { get; }
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 33a7d50d86178eb43a36d5e8bdd70982
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -11,7 +11,7 @@ using UnityEngine.Serialization;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public abstract class MonoEntityTemplateBase : MonoBehaviour, IEntityTemplate
|
||||
public abstract class MonoEntityTemplateBase : MonoBehaviour, ITemplateNode
|
||||
{
|
||||
public abstract void Apply(short worldID, int entityID);
|
||||
}
|
||||
@ -22,20 +22,13 @@ namespace DCFApixels.DragonECS
|
||||
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsUnityConsts.ENTITY_BUILDING_GROUP)]
|
||||
[MetaDescription(EcsConsts.AUTHOR, nameof(MonoBehaviour) + " implementation of an entity template. Templates are a set of components that are applied to entities.")]
|
||||
[MetaID("DragonECS_C734BA8092014833C14F21E05D7B1551")]
|
||||
public class MonoEntityTemplate : MonoEntityTemplateBase, IEntityTemplateInternal
|
||||
public class MonoEntityTemplate : MonoEntityTemplateBase, ITemplateNode
|
||||
{
|
||||
[SerializeReference]
|
||||
[ReferenceButton(true, typeof(IComponentTemplate))]
|
||||
[FormerlySerializedAs("_components")]
|
||||
private IComponentTemplate[] _componentTemplates;
|
||||
|
||||
#region Properties
|
||||
string IEntityTemplateInternal.ComponentsPropertyName
|
||||
{
|
||||
get { return nameof(_componentTemplates); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public ReadOnlySpan<IComponentTemplate> GetComponentTemplates()
|
||||
{
|
||||
|
||||
@ -11,7 +11,7 @@ using UnityEngine.Serialization;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public abstract class ScriptableEntityTemplateBase : ScriptableObject, IEntityTemplate
|
||||
public abstract class ScriptableEntityTemplateBase : ScriptableObject, ITemplateNode
|
||||
{
|
||||
public abstract void Apply(short worldID, int entityID);
|
||||
}
|
||||
@ -21,7 +21,7 @@ namespace DCFApixels.DragonECS
|
||||
[MetaDescription(EcsConsts.AUTHOR, nameof(ScriptableObject) + " implementation of an entity template. Templates are a set of components that are applied to entities.")]
|
||||
[CreateAssetMenu(fileName = nameof(ScriptableEntityTemplate), menuName = EcsConsts.FRAMEWORK_NAME + "/" + nameof(ScriptableEntityTemplate), order = 1)]
|
||||
[MetaID("DragonECS_7C4DBA809201D959401A5BDFB6363EC0")]
|
||||
public class ScriptableEntityTemplate : ScriptableEntityTemplateBase, IEntityTemplateInternal
|
||||
public class ScriptableEntityTemplate : ScriptableEntityTemplateBase, ITemplateNode
|
||||
{
|
||||
[SerializeField]
|
||||
private ScriptableEntityTemplateBase[] _templates;
|
||||
@ -30,13 +30,6 @@ namespace DCFApixels.DragonECS
|
||||
[FormerlySerializedAs("_components")]
|
||||
private IComponentTemplate[] _componentTemplates;
|
||||
|
||||
#region Properties
|
||||
string IEntityTemplateInternal.ComponentsPropertyName
|
||||
{
|
||||
get { return nameof(_componentTemplates); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public ReadOnlySpan<ScriptableEntityTemplateBase> GetTemplates()
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user