mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 09:54:35 +08:00
update readme
This commit is contained in:
parent
ef18594f82
commit
0f3b1c1e1f
146
README-RU.md
146
README-RU.md
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
</br>
|
</br>
|
||||||
|
|
||||||
DragonECS - это [ECS](https://en.wikipedia.org/wiki/Entity_component_system) фреймворк нацеленный на максимальную удобность, модульность, расширяемость и производительность динамического изменения сущностей. Разработан на чистом C#, без зависимостей и генерации кода. Вдохновлен [LeoEcs](https://github.com/Leopotam/ecslite).
|
DragonECS - это [ECS](https://en.wikipedia.org/wiki/Entity_component_system) фреймворк нацеленный на максимальную удобность, модульность, расширяемость и производительность динамического изменения сущностей. Разработан на чистом C#, без зависимостей и генерации кода. Вдохновлен [LeoEcs Lite](https://github.com/Leopotam/ecslite).
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> Проект предрелизной версии, поэтому API может меняться. В ветке main актуальная и рабочая версия.</br>
|
> Проект предрелизной версии, поэтому API может меняться. В ветке main актуальная и рабочая версия.</br>
|
||||||
@ -58,7 +58,7 @@ DragonECS - это [ECS](https://en.wikipedia.org/wiki/Entity_component_system)
|
|||||||
- [Построение](#построение)
|
- [Построение](#построение)
|
||||||
- [Внедрение зависимостей](#внедрение-зависимостей)
|
- [Внедрение зависимостей](#внедрение-зависимостей)
|
||||||
- [Модули](#модули)
|
- [Модули](#модули)
|
||||||
- [Слои](#слои)
|
- [Сортировка](#сортировка)
|
||||||
- [Процессы](#процессы)
|
- [Процессы](#процессы)
|
||||||
- [Мир](#мир)
|
- [Мир](#мир)
|
||||||
- [Пул](#пул)
|
- [Пул](#пул)
|
||||||
@ -149,18 +149,17 @@ if (entity.TryGetID(out int entityID)) { }
|
|||||||
|
|
||||||
> **NOTICE:** Сущности не могут существовать без компонентов, пустые сущности будут автоматически удаляться сразу после удаления последнего компонента либо в конце тика.
|
> **NOTICE:** Сущности не могут существовать без компонентов, пустые сущности будут автоматически удаляться сразу после удаления последнего компонента либо в конце тика.
|
||||||
## Component
|
## Component
|
||||||
**Компоненты** - это данные для сущностей. Обязаны реализовывать интерфейс `IEcsComponent` или другой указывающий вид компонента.
|
**Компоненты** - это данные которые крепятся к сущностям.
|
||||||
```c#
|
```c#
|
||||||
|
// Компоненты IEcsComponent хранятся в обычном хранилище.
|
||||||
struct Health : IEcsComponent
|
struct Health : IEcsComponent
|
||||||
{
|
{
|
||||||
public float health;
|
public float health;
|
||||||
public int armor;
|
public int armor;
|
||||||
}
|
}
|
||||||
|
// Компоненты с IEcsTagComponent хранятся в оптимизированном для тегов хранилище.
|
||||||
struct PlayerTag : IEcsTagComponent {}
|
struct PlayerTag : IEcsTagComponent {}
|
||||||
```
|
```
|
||||||
Встроенные виды компонентов:
|
|
||||||
* `IEcsComponent` - Компоненты с данными. Универсальный тип компонентов.
|
|
||||||
* `IEcsTagComponent` - Компоненты-теги. Без данных.
|
|
||||||
|
|
||||||
## System
|
## System
|
||||||
**Системы** - это основная логика, тут задается поведение сущностей. Существуют в виде пользовательских классов, реализующих как минимум один из интерфейсов процессов. Основные процессы:
|
**Системы** - это основная логика, тут задается поведение сущностей. Существуют в виде пользовательских классов, реализующих как минимум один из интерфейсов процессов. Основные процессы:
|
||||||
@ -271,8 +270,10 @@ EcsPipeline pipeline = EcsPipeline.New()
|
|||||||
.BuildAndInit();
|
.BuildAndInit();
|
||||||
```
|
```
|
||||||
|
|
||||||
### Слои
|
### Сортировка
|
||||||
Очередь систем можно разбить на слои. Слой определяет место в очереди для вставки систем. Например, если необходимо чтобы какая-то система была вставлена в конце очереди, вне зависимости от места добавления, эту систему можно добавить в слой EcsConsts.END_LAYER.
|
Дла управления расположением систем в пайплайне, вне зависимости от порядка добавления, есть 2 способа: Слои и Порядок сортировки.
|
||||||
|
#### Слои
|
||||||
|
Слой определяет место в пайплайне для вставки систем. Например, если необходимо чтобы система была вставлена в конце пайплайна, эту систему можно добавить в слой `EcsConsts.END_LAYER`.
|
||||||
``` c#
|
``` c#
|
||||||
const string SOME_LAYER = nameof(SOME_LAYER);
|
const string SOME_LAYER = nameof(SOME_LAYER);
|
||||||
EcsPipeline pipeline = EcsPipeline.New()
|
EcsPipeline pipeline = EcsPipeline.New()
|
||||||
@ -287,9 +288,20 @@ EcsPipeline pipeline = EcsPipeline.New()
|
|||||||
Встроенные слои расположены в следующем порядке:
|
Встроенные слои расположены в следующем порядке:
|
||||||
* `EcsConst.PRE_BEGIN_LAYER`
|
* `EcsConst.PRE_BEGIN_LAYER`
|
||||||
* `EcsConst.BEGIN_LAYER`
|
* `EcsConst.BEGIN_LAYER`
|
||||||
* `EcsConst.BASIC_LAYER` (Если при добавлении системы не указать слой, то она будет добавлена сюда)
|
* `EcsConst.BASIC_LAYER` (По умолчанию системы добавляются сюда)
|
||||||
* `EcsConst.END_LAYER`
|
* `EcsConst.END_LAYER`
|
||||||
* `EcsConst.POST_END_LAYER`
|
* `EcsConst.POST_END_LAYER`
|
||||||
|
#### Порядок сортировки
|
||||||
|
Для сортировки систем в рамках слоя используется int значение порядка сортировки. По умолчанию системы добавляются с sortOrder = 0.
|
||||||
|
``` c#
|
||||||
|
EcsPipeline pipeline = EcsPipeline.New()
|
||||||
|
// ...
|
||||||
|
// Система SomeSystem будет вставлена в слой EcsConsts.BEGIN_LAYER
|
||||||
|
// и расположена после систем с sortOrder меньше 10.
|
||||||
|
.Add(New SomeSystem(), EcsConsts.BEGIN_LAYER, 10)
|
||||||
|
// ...
|
||||||
|
.BuildAndInit();
|
||||||
|
```
|
||||||
|
|
||||||
## Процессы
|
## Процессы
|
||||||
Процессы - это очереди систем реализующие общий интерфейс, например `IEcsRun`. Для запуска процессов используются Runner-ы. Встроенные процессы запускаются автоматически. Есть возможность реализации пользовательских процессов.
|
Процессы - это очереди систем реализующие общий интерфейс, например `IEcsRun`. Для запуска процессов используются Runner-ы. Встроенные процессы запускаются автоматически. Есть возможность реализации пользовательских процессов.
|
||||||
@ -345,17 +357,20 @@ _pipeline.GetRunnerInstance<DoSomethingProcessRunner>.Do()
|
|||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Мир
|
## Мир
|
||||||
Является контейнером для сущностей и компонентов.
|
Контейнер для сущностей и компонентов.
|
||||||
``` c#
|
``` c#
|
||||||
// Создание экземпляра мира.
|
// Создание экземпляра мира.
|
||||||
_world = new EcsDefaultWorld();
|
_world = new EcsDefaultWorld();
|
||||||
|
|
||||||
// Создание и удаление сущности по примеру из раздела Сущности.
|
// Создание и удаление сущности по примеру из раздела Сущности.
|
||||||
var e = _world.NewEntity();
|
var e = _world.NewEntity();
|
||||||
_world.DelEntity(e);
|
_world.DelEntity(e);
|
||||||
```
|
|
||||||
> **NOTICE:** Необходимо вызывать EcsWorld.Destroy() у экземпляра мира если он больше не используется, иначе он будет висеть в памяти.
|
|
||||||
|
|
||||||
### Конфигурация мира
|
// Уничтожение мира и освобождение ресурсов. Обязательно вызывать, иначе он будет висеть в памяти.
|
||||||
|
_world.Destroy();
|
||||||
|
```
|
||||||
|
> Миры изолированы друг от друга и могут обрабатываться в отдельных потоках. Но мультипоточная обработка одного мира поддерживается только при отсутсвии добавления/удаляения компонентов у сущностей.
|
||||||
|
|
||||||
Для инициализации мира сразу необходимого размера и сокращения времени прогрева, в конструктор можно передать экземпляр `EcsWorldConfig`.
|
Для инициализации мира сразу необходимого размера и сокращения времени прогрева, в конструктор можно передать экземпляр `EcsWorldConfig`.
|
||||||
|
|
||||||
``` c#
|
``` c#
|
||||||
@ -363,14 +378,16 @@ EcsWorldConfig config = new EcsWorldConfig(
|
|||||||
// Предварительно инициализирует вместимость мира для 2000 сущностей.
|
// Предварительно инициализирует вместимость мира для 2000 сущностей.
|
||||||
entitiesCapacity: 2000,
|
entitiesCapacity: 2000,
|
||||||
// Предварительно инициализирует вместимость пулов для 2000 компонентов.
|
// Предварительно инициализирует вместимость пулов для 2000 компонентов.
|
||||||
poolComponentsCapacity: 2000);
|
poolComponentsCapacity: 2000
|
||||||
|
// ... Есть и другие параметры
|
||||||
|
);
|
||||||
_world = new EcsDefaultWorld(config);
|
_world = new EcsDefaultWorld(config);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Пул
|
## Пул
|
||||||
Является хранилищем для компонентов, предоставляет методы для добавления/чтения/редактирования/удаления компонентов на сущности. Есть несколько видов пулов, для разных целей:
|
Хранилище для компонентов, пул предоставляет методы для добавления/чтения/редактирования/удаления компонентов на сущности. Есть несколько видов пулов, для разных видов компонентов:
|
||||||
* `EcsPool` - универсальный пул, хранит struct-компоненты реализующие интерфейс `IEcsComponent`;
|
* `EcsPool` - универсальный пул, хранит struct-компоненты реализующие интерфейс `IEcsComponent`;
|
||||||
* `EcsTagPool` - специальный пул для пустых компонентов-тегов, хранит struct-компоненты с `IEcsTagComponent` как bool значения, что в сравнении с реализацией `EcsPool` имеет лучше оптимизацию памяти и скорости;
|
* `EcsTagPool` - специальный пул, оптимизированный под компоненты-теги, хранит struct-компоненты с `IEcsTagComponent`;
|
||||||
|
|
||||||
Пулы имеют 5 основных метода и их разновидности:
|
Пулы имеют 5 основных метода и их разновидности:
|
||||||
``` c#
|
``` c#
|
||||||
@ -392,12 +409,50 @@ if (poses.Has(entityID)) { /* ... */ }
|
|||||||
// Удалит компонент у сущности, бросит исключение если у сущности нет этого компонента.
|
// Удалит компонент у сущности, бросит исключение если у сущности нет этого компонента.
|
||||||
poses.Del(entityID);
|
poses.Del(entityID);
|
||||||
```
|
```
|
||||||
|
> [!WARNING]
|
||||||
|
> В `Release` сброке отключаются проверки на исключения.
|
||||||
|
|
||||||
> Есть "безопасные" методы, которые сначала выполнят проверку наличия/отсутствия компонента, названия таких методов начинаются с `Try`.
|
> Есть "безопасные" методы, которые сначала выполнят проверку наличия/отсутствия компонента, названия таких методов начинаются с `Try`.
|
||||||
|
|
||||||
> Имеется возможность реализации пользовательского пула. Эта функция будет описана в ближайшее время.
|
> Имеется возможность реализации пользовательского пула. Эта функция будет описана в ближайшее время.
|
||||||
|
|
||||||
|
## Маска
|
||||||
|
Применяется для фильтрации сущностей по наличию или отсутствию компонентов.
|
||||||
|
``` c#
|
||||||
|
// Создание маски которая проверяет что у сущностей есть компоненты
|
||||||
|
// SomeCmp1 и SomeCmp2, но нет компонента SomeCmp3.
|
||||||
|
EcsMask mask = EcsMask.New(_world)
|
||||||
|
// Inc - Условие наличия компонента.
|
||||||
|
.Inc<SomeCmp1>()
|
||||||
|
.Inc<SomeCmp2>()
|
||||||
|
// Exc - Условие отсутствия компонента.
|
||||||
|
.Exc<SomeCmp3>()
|
||||||
|
.Build();
|
||||||
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Статическая маска</summary>
|
||||||
|
|
||||||
|
`EcsMask` привязаны к конкретным экземплярам мира которые необходимо передавать в `EcsMask.New(world)`, но есть `EcsStaticMask` которую можно создать без привязки к миру.
|
||||||
|
|
||||||
|
``` c#
|
||||||
|
class SomeSystem : IEcsRun
|
||||||
|
{
|
||||||
|
// EcsStaticMask можно создавать в статических полях.
|
||||||
|
static EcsStaticMask _staticMask = EcsStaticMask.Inc<SomeCmp1>().Inc<SomeCmp2>().Exc<SomeCmp3>().Build();
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
``` c#
|
||||||
|
// Конвертация в обычную маску.
|
||||||
|
EcsMask mask = _staticMask.ToMask(_world);
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## Аспект
|
## Аспект
|
||||||
Это пользовательские классы наследуемые от `EcsAspect` и используемые для взаимодействия с сущностями. Аспекты одновременно являются кешем пулов и маской компонентов для фильтрации сущностей. Можно рассматривать аспекты как описание того с какими сущностями работает система.
|
Пользовательские классы наследуемые от `EcsAspect` и используемые для взаимодействия с сущностями. Аспекты одновременно являются кешем пулов и содержат маску. Можно рассматривать аспекты как описание того с какими сущностями работает система.
|
||||||
|
|
||||||
Упрощенный синтаксис:
|
Упрощенный синтаксис:
|
||||||
``` c#
|
``` c#
|
||||||
@ -418,7 +473,9 @@ class Aspect : EcsAspect
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Явный синтаксис (результат идентичен примеру выше):
|
<details>
|
||||||
|
<summary>Явный синтаксис (результат идентичен примеру выше):</summary>
|
||||||
|
|
||||||
``` c#
|
``` c#
|
||||||
using DCFApixels.DragonECS;
|
using DCFApixels.DragonECS;
|
||||||
// ...
|
// ...
|
||||||
@ -435,6 +492,8 @@ class Aspect : EcsAspect
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Комбинирование аспектов</summary>
|
<summary>Комбинирование аспектов</summary>
|
||||||
|
|
||||||
@ -470,16 +529,23 @@ class Aspect : EcsAspect
|
|||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Запросы
|
## Запросы
|
||||||
Что бы получить необходимый набор сущностей используется метод-запрос `EcsWorld.Where<TAspect>(out TAspect aspect)`. В качестве `TAspect` указывается аспект, сущности будут отфильтрованны по маске указанного аспекта. Запрос `Where` применим как к `EcsWorld` так и коллекциям фреймворка (в этом плане Where чем-то похож на аналогичный из Linq).
|
Фильтруют сущности и выдают коллекции сущностей удовлетворяющие определенным условиям. Встроенный запрос `Where` фильтрует на соответствие условиям маски компонентов и имеет несколько перегрузок:
|
||||||
Пример:
|
+ `EcsWorld.Where(EcsMask mask)` - Обычная фильтрация по маске;
|
||||||
|
+ `EcsWorld.Where<TAspect>(out TAspect aspect)` - Сочетает в себе фильтрацию по маске из аспекта и получение аспекта;
|
||||||
|
|
||||||
|
Запрос `Where` применим как к `EcsWorld` так и коллекциям фреймворка (в этом плане Where чем-то похож на аналогичный из Linq). Так же имеются перегрузки для сортировки сущностей по `Comparison<int>`.
|
||||||
|
|
||||||
|
Пример системы:
|
||||||
``` c#
|
``` c#
|
||||||
public class SomeDamageSystem : IEcsRun, IEcsInject<EcsDefaultWorld>
|
public class SomeDamageSystem : IEcsRun, IEcsInject<EcsDefaultWorld>
|
||||||
{
|
{
|
||||||
class Aspect : EcsAspect
|
class Aspect : EcsAspect
|
||||||
{
|
{
|
||||||
public EcsPool<Health> healths = Inc;
|
public EcsPool<Health> healths = Inc;
|
||||||
public EcsPool<DamageSignal> damageSignals = Inc;
|
public EcsPool<DamageSignal> damageSignals = Inc;
|
||||||
public EcsTagPool<IsInvulnerable> isInvulnerables = Exc;
|
public EcsTagPool<IsInvulnerable> isInvulnerables = Exc;
|
||||||
|
// Наличие или отсутвие этого компонента не проверяется.
|
||||||
|
public EcsTagPool<IsDiedSignal> isDiedSignals = Opt;
|
||||||
}
|
}
|
||||||
EcsDefaultWorld _world;
|
EcsDefaultWorld _world;
|
||||||
public void Inject(EcsDefaultWorld world) => _world = world;
|
public void Inject(EcsDefaultWorld world) => _world = world;
|
||||||
@ -489,7 +555,15 @@ public class SomeDamageSystem : IEcsRun, IEcsInject<EcsDefaultWorld>
|
|||||||
foreach (var e in _world.Where(out Aspect a))
|
foreach (var e in _world.Where(out Aspect a))
|
||||||
{
|
{
|
||||||
// Сюда попадают сущности с компонентами Health, DamageSignal и без IsInvulnerable.
|
// Сюда попадают сущности с компонентами Health, DamageSignal и без IsInvulnerable.
|
||||||
a.healths.Get(e).points -= a.damageSignals.Get(e).points;
|
ref var health = ref a.healths.Get(e);
|
||||||
|
if(health.points > 0)
|
||||||
|
{
|
||||||
|
health.points -= a.damageSignals.Get(e).points;
|
||||||
|
if(health.points <= 0)
|
||||||
|
{ // Создаем сигнал другим системам о том что сущность умерла.
|
||||||
|
a.isDiedSignals.TryAdd(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -689,6 +763,9 @@ using DCFApixels.DragonECS;
|
|||||||
|
|
||||||
// Добавляет описание типу.
|
// Добавляет описание типу.
|
||||||
[MetaDescription("The quick brown fox jumps over the lazy dog")]
|
[MetaDescription("The quick brown fox jumps over the lazy dog")]
|
||||||
|
|
||||||
|
// Добавляет строковый уникальный идентификатор.
|
||||||
|
[MetaID("8D56F0949201D0C84465B7A6C586DCD6")] // Строки должны быть уникальными, и не допускают символы ,<> .
|
||||||
|
|
||||||
// Добавляет строковые теги.
|
// Добавляет строковые теги.
|
||||||
[MetaTags("Tag1", "Tag2", ...)] // [MetaTags(MetaTags.HIDDEN))] чтобы скрыть в редакторе
|
[MetaTags("Tag1", "Tag2", ...)] // [MetaTags(MetaTags.HIDDEN))] чтобы скрыть в редакторе
|
||||||
@ -700,17 +777,16 @@ TypeMeta typeMeta = someComponent.GetMeta();
|
|||||||
// или
|
// или
|
||||||
TypeMeta typeMeta = pool.ComponentType.ToMeta();
|
TypeMeta typeMeta = pool.ComponentType.ToMeta();
|
||||||
|
|
||||||
var name = typeMeta.Name;
|
var name = typeMeta.Name; // [MetaName]
|
||||||
var color = typeMeta.Color;
|
var group = typeMeta.Group; // [MetaGroup]
|
||||||
var description = typeMeta.Description;
|
var color = typeMeta.Color; // [MetaColor]
|
||||||
var group = typeMeta.Group;
|
var description = typeMeta.Description; // [MetaDescription]
|
||||||
var tags = typeMeta.Tags;
|
var metaID = typeMeta.MetaID; // [MetaID]
|
||||||
|
var tags = typeMeta.Tags; // [MetaTags]
|
||||||
```
|
```
|
||||||
|
|
||||||
## EcsDebug
|
## EcsDebug
|
||||||
Имеет набор методов для отладки и логирования. Реализован как статический класс вызывающий методы Debug-сервисов. Debug-сервисы - это посредники между системами отладки среды и EcsDebug. Это позволяет не изменяя отладочный код проекта, переносить проект на другие движки, достаточно только реализовать соответствующий Debug-сервис.
|
Вспомогательный тип с набором методов для отладки и логирования. Реализован как статический класс вызывающий методы Debug-сервисов. Debug-сервисы - это посредники между EcsDebug и инструментами отладки среды. Такая реализация позволяет не изменяя отладочный код, менять его поведение или переносить проект в другие среды, достаточно только реализовать соответствующий Debug-сервис.
|
||||||
|
|
||||||
По умолчанию используется `DefaultDebugService` который выводит логи в консоль. Для реализации пользовательского создайте класс наследуемый от `DebugService` и реализуйте абстрактные члены класса.
|
|
||||||
|
|
||||||
``` c#
|
``` c#
|
||||||
// Вывод лога.
|
// Вывод лога.
|
||||||
@ -726,12 +802,17 @@ EcsDebug.Break();
|
|||||||
EcsDebug.Set<OtherDebugService>();
|
EcsDebug.Set<OtherDebugService>();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> По умолчанию используется `DefaultDebugService` который выводит логи в консоль. Для реализации пользовательского создайте класс наследуемый от `DebugService` и реализуйте абстрактные члены класса.
|
||||||
|
|
||||||
|
> `EcsDebug` потокобезопасен, за счет того что каждый поток использует свой изолированный экземпляр сервиса. Экземпляры для потоков создаются в абстрактном методе `DebugService.CreateThreadInstance`.
|
||||||
|
|
||||||
## Профилирование
|
## Профилирование
|
||||||
|
За реализацию профайлера так же отвечает Debug-сервис. Для выделения участка кода используется `EcsProfilerMarker`;
|
||||||
``` c#
|
``` c#
|
||||||
// Создание маркера с именем SomeMarker.
|
// Создание маркера с именем SomeMarker.
|
||||||
private static readonly EcsProfilerMarker marker = new EcsProfilerMarker("SomeMarker");
|
private static readonly EcsProfilerMarker marker = new EcsProfilerMarker("SomeMarker");
|
||||||
|
|
||||||
...
|
// ...
|
||||||
|
|
||||||
marker.Begin();
|
marker.Begin();
|
||||||
// Код для которого замеряется скорость.
|
// Код для которого замеряется скорость.
|
||||||
@ -744,6 +825,7 @@ using (marker.Auto())
|
|||||||
// Код для которого замеряется скорость.
|
// Код для которого замеряется скорость.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
> `DefaultDebugService` использует реализацию на основе `Stopwatch` и выводом в консоль.
|
||||||
|
|
||||||
</br>
|
</br>
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
</br>
|
</br>
|
||||||
|
|
||||||
DragonECS 是一个[实体组件系统](https://www.imooc.com/article/331544)框架。专注于提升便利性、模块性、可扩展性和动态实体修改性能。 用纯C#开发的,没有依赖和代码生成。灵感来自于[LeoEcs](https://github.com/Leopotam/ecslite)。
|
DragonECS 是一个[实体组件系统](https://www.imooc.com/article/331544)框架。专注于提升便利性、模块性、可扩展性和动态实体修改性能。 用纯C#开发的,没有依赖和代码生成。灵感来自于[LeoEcs Lite](https://github.com/Leopotam/ecslite)。
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> 该框架是预发布版本,因此 API 可能会有变化。在 `main` 分支中是当前的工作版本。</br>
|
> 该框架是预发布版本,因此 API 可能会有变化。在 `main` 分支中是当前的工作版本。</br>
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
</br>
|
</br>
|
||||||
|
|
||||||
The [ECS](https://en.wikipedia.org/wiki/Entity_component_system) Framework aims to maximize usability, modularity, extensibility and performance of dynamic entity changes. Without code generation and dependencies. Inspired by [LeoEcs](https://github.com/Leopotam/ecslite).
|
The [ECS](https://en.wikipedia.org/wiki/Entity_component_system) Framework aims to maximize usability, modularity, extensibility and performance of dynamic entity changes. Without code generation and dependencies. Inspired by [LeoEcs Lite](https://github.com/Leopotam/ecslite).
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> The project is a work in progress, API may change.
|
> The project is a work in progress, API may change.
|
||||||
|
Loading…
Reference in New Issue
Block a user