diff --git a/README-RU.md b/README-RU.md
index 930d102..ce2d01c 100644
--- a/README-RU.md
+++ b/README-RU.md
@@ -20,28 +20,26 @@
-
+ 
Русский
|
-
+ 
English
|
-
+ 
中文
|
-
-
-DragonECS - это [ECS](https://en.wikipedia.org/wiki/Entity_component_system) фреймворк нацеленный на максимальную удобность, модульность, расширяемость и производительность динамического изменения сущностей. Разработан на чистом C#, без зависимостей и генерации кода. Вдохновлен [LeoEcs Lite](https://github.com/Leopotam/ecslite).
+DragonECS - это [ECS](https://en.wikipedia.org/wiki/Entity_component_system) фреймворк, нацеленный на максимальную удобность, модульность, расширяемость и производительность динамического изменения сущностей. Разработан на чистом C#, без зависимостей и генерации кода. Вдохновлен [LeoEcs Lite](https://github.com/Leopotam/ecslite).
> [!WARNING]
> Проект предрелизной версии, поэтому API может меняться. В ветке main актуальная и рабочая версия.
@@ -81,20 +79,20 @@ DragonECS - это [ECS](https://en.wikipedia.org/wiki/Entity_component_system)
- [FAQ](#faq)
- [Обратная связь](#обратная-связь)
-
+
# Установка
Семантика версионирования - [Открыть](https://gist.github.com/DCFApixels/e53281d4628b19fe5278f3e77a7da9e8#file-dcfapixels_versioning_ru-md)
## Окружение
Обязательные требования:
-+ Минимальная версия C# 7.3;
++ Минимальная версия C#: 7.3.
Поддерживает:
+ NativeAOT;
+ Игровые движки с C#: Unity, Godot, MonoGame и т.д.
-Протестировано:
-+ **Unity:** Минимальная версия 2021.2.0;
+Протестировано на:
+* **Unity:** Минимальная версия 2021.2.0.
## Установка для Unity
> Рекомендуется так же установить расширение [Интеграция с движком Unity](https://github.com/DCFApixels/DragonECS-Unity)
@@ -110,8 +108,8 @@ https://github.com/DCFApixels/DragonECS.git
* ### В виде исходников
Можно так же напрямую скопировать в проект исходники фреймворка.
+
-
# Расширения
* Интеграции:
@@ -131,14 +129,14 @@ https://github.com/DCFApixels/DragonECS.git
* [Шаблоны кода IDE](https://gist.github.com/ctzcs/0ba948b0e53aa41fe1c87796a401660b) и [для Unity](https://gist.github.com/ctzcs/d4c7730cf6cd984fe6f9e0e3f108a0f1)
> *Твое расширение? Если разрабатываешь расширение для DragonECS, пиши [сюда](#обратная-связь).
-
+
# Основные концепции
## Entity
-**Сущности** - это то к чему крепятся данные. Для доступа к сущности используются идентификаторы двух типов:
+**Сущности** - это то, к чему крепятся данные. Для доступа к сущности используются идентификаторы двух типов:
* `int` - однократный идентификатор, применяется в пределах одного тика. Не рекомендуется использовать для хранения;
* `entlong` - долговременный идентификатор, содержит метку поколения, что делает его уникальным навсегда. Подходит для хранения.
-``` c#
+```c#
// Создание новой сущности в мире.
int entityID = _world.NewEntity();
@@ -156,7 +154,7 @@ int newEntityID = _world.CloneEntity(entityID);
Работа с entlong
-``` c#
+```c#
// Конвертация int в entlong.
entlong entity = _world.GetEntityLong(entityID);
// упрощенная версия
@@ -216,7 +214,7 @@ class SomeSystem : IEcsPreInit, IEcsInit, IEcsRun, IEcsDestroy
Пример системы
-``` c#
+```c#
// Система
class DamageSystem : IEcsRun, IEcsInject
{
@@ -254,7 +252,7 @@ public struct Health : IEcsComponent
-
+
# Концепции фреймворка
## Пайплайн
@@ -285,9 +283,9 @@ class SomeSystem : IEcsRun, IEcsPipelineMember
```
> Для одновременного построения и инициализации есть метод Builder.BuildAndInit();
### Внедрение зависимостей
-Фреймворк реализует внедрение зависимостей для систем. это процесс который запускается вместе с инициализацией пайплайна и внедряет данные переданные в Builder.
+Фреймворк реализует внедрение зависимостей для систем. Это процесс, который запускается вместе с инициализацией пайплайна и внедряет данные, переданные в Builder.
-``` c#
+```c#
class SomeDataA { /* ... */ }
class SomeDataB : SomeDataA { /* ... */ }
@@ -325,7 +323,7 @@ class SomeSystem : IEcsInject, IEcsRun
### Модули
Группы систем реализующие общую фичу можно объединять в модули, и просто добавлять модули в Pipeline.
-``` c#
+```c#
using DCFApixels.DragonECS;
class Module1 : IEcsModule
{
@@ -338,7 +336,7 @@ class Module1 : IEcsModule
}
}
```
-``` c#
+```c#
EcsPipeline pipeline = EcsPipeline.New()
// ...
.AddModule(new Module1())
@@ -347,10 +345,10 @@ EcsPipeline pipeline = EcsPipeline.New()
```
### Сортировка
-Дла управления расположением систем в пайплайне, вне зависимости от порядка добавления, есть 2 способа: Слои и Порядок сортировки.
+Для управления расположением систем в пайплайне, вне зависимости от порядка добавления, есть 2 способа: Слои и Порядок сортировки.
#### Слои
Слой определяет место в пайплайне для вставки систем. Например, если необходимо чтобы система была вставлена в конце пайплайна, эту систему можно добавить в слой `EcsConsts.END_LAYER`.
-``` c#
+```c#
const string SOME_LAYER = nameof(SOME_LAYER);
EcsPipeline pipeline = EcsPipeline.New()
// ...
@@ -362,14 +360,14 @@ EcsPipeline pipeline = EcsPipeline.New()
.BuildAndInit();
```
Встроенные слои расположены в следующем порядке:
-* `EcsConst.PRE_BEGIN_LAYER`
-* `EcsConst.BEGIN_LAYER`
-* `EcsConst.BASIC_LAYER` (По умолчанию системы добавляются сюда)
-* `EcsConst.END_LAYER`
-* `EcsConst.POST_END_LAYER`
+* `EcsConsts.PRE_BEGIN_LAYER`
+* `EcsConsts.BEGIN_LAYER`
+* `EcsConsts.BASIC_LAYER` (По умолчанию системы добавляются сюда)
+* `EcsConsts.END_LAYER`
+* `EcsConsts.POST_END_LAYER`
#### Порядок сортировки
Для сортировки систем в рамках слоя используется int значение порядка сортировки. По умолчанию системы добавляются с `sortOrder = 0`.
-``` c#
+```c#
EcsPipeline pipeline = EcsPipeline.New()
// ...
// Система SomeSystem будет вставлена в слой EcsConsts.BEGIN_LAYER
@@ -395,7 +393,7 @@ EcsPipeline pipeline = EcsPipeline.New()
Пользовательские процессы
Для добавления нового процесса создайте интерфейс наследованный от `IEcsProcess` и создайте раннер для него. Раннер это класс реализующий интерфейс запускаемого процесса и наследуемый от `EcsRunner`. Пример:
-``` c#
+```c#
// Интерфейс процесса.
interface IDoSomethingProcess : IEcsProcess
{
@@ -421,10 +419,10 @@ _pipeline = EcsPipeline.New()
.BuildAndInit();
// Запуск раннера если раннер был добавлен.
-_pipeline.GetRunner.Do()
+_pipeline.GetRunner().Do();
-// Или если раннер не был добавлен(Вызов GetRunnerInstance так же добавит раннер в пайплайн).
-_pipeline.GetRunnerInstance.Do()
+// Или если раннер не был добавлен (вызов GetRunnerInstance также добавит раннер в пайплайн).
+_pipeline.GetRunnerInstance().Do();
```
@@ -541,9 +539,9 @@ poses.Del(entityID);
Обычно маски не используются в чистом виде, а являются частью [Аспекта](#Аспект).
-``` c#
-// Создание маски с улосвием наличия компонентов SomeCmp1 и SomeCmp2,
-// и с улосвием отсутсвия компонента SomeCmp3.
+```c#
+// Создание маски с условием наличия компонентов SomeCmp1 и SomeCmp2,
+// и с условием отсутствия компонента SomeCmp3.
EcsMask mask = EcsMask.New(_world)
// Inc - Условие наличия компонента.
.Inc()
@@ -704,7 +702,7 @@ public class SomeDamageSystem : IEcsRun, IEcsInject
``` c#
// Запрос Where возвращает сущности в виде EcsSpan.
EcsSpan es = _world.Where(out Aspect a);
-// Итерироваться можно по foreach и for.
+// Итерироваться можно с помощью `foreach` и `for`.
foreach (var e in es)
{
// ...
@@ -737,7 +735,7 @@ group.Remove(entityID);
``` c#
// Запрос WhereToGroup возвращает сущности в виде группы только для чтения EcsReadonlyGroup.
EcsReadonlyGroup group = _world.WhereToGroup(out Aspect a);
-// Итерироваться можно по foreach и for.
+// Итерироваться можно с помощью `foreach` и `for`.
foreach (var e in group)
{
// ...
@@ -963,7 +961,7 @@ using (_marker.Auto())
+ `DRAGONECS_STABILITY_MODE` - включает опускаемые в релизном билде проверки.
+ `DRAGONECS_DISABLE_CATH_EXCEPTIONS` - Выключает поведение по умолчанию по обработке исключений. По умолчанию фреймворк будет ловить исключения с выводом информации из исключений через EcsDebug и продолжать работу.
+ `REFLECTION_DISABLED` - Полностью ограничивает работу фреймворка с Reflection.
-+ `DISABLE_DEBUG` - Для среды где не поддерживается ручное отключение DEBUG, например Unity.
++ `DISABLE_DEBUG` - Для среды, где не поддерживается ручное отключение DEBUG, например Unity.
@@ -1124,7 +1122,7 @@ public struct WorldComponent : IEcsWorldComponent
# FAQ
## Как Выключать/Включать системы?
-Напрямую - никак.
+Напрямую — никак.
Обычно потребность выключить/включить систему появляется когда поменялось общее состояние игры, это может так же значить что нужно переключить сразу группу систем, все это в совокупности можно рассматривать как изменения процессов. Есть 2 решения:
+ Если изменения процесса глобальные, то создать новый `EcsPipeline` и в цикле обновления движка запускать соответствующий пайплайн.
+ Разделить `IEcsRun` на несколько процессов и в цикле обновления движка запускать соответствующий процесс. Для этого создайте новый интерфейс процесса, раннер для запуска этого интерфейса и получайте раннер через `EcsPipeline.GetRunner()`.
diff --git a/README-ZH.md b/README-ZH.md
index 6e6777c..27dd568 100644
--- a/README-ZH.md
+++ b/README-ZH.md
@@ -20,19 +20,19 @@
-
+ 
Русский
|
-
+ 
English
|
-
+ 
中文
|
@@ -52,6 +52,7 @@ DragonECS 是一个[实体组件系统](https://www.imooc.com/article/331544)框
## 目录
- [安装](#安装)
+- [扩展](#扩展)
- [基础概念](#基础概念)
- [实体](#实体)
- [组件](#组件)
@@ -79,7 +80,6 @@ DragonECS 是一个[实体组件系统](https://www.imooc.com/article/331544)框
- [世界组件](#世界组件)
- [配置](#配置)
- [使用DragonECS的项目](#使用dragonecs的项目)
-- [扩展](#扩展)
- [FAQ](#faq)
- [反馈](#反馈)
@@ -89,14 +89,14 @@ DragonECS 是一个[实体组件系统](https://www.imooc.com/article/331544)框
版本的语义 [[打开]](https://gist.github.com/DCFApixels/e53281d4628b19fe5278f3e77a7da9e8#file-dcfapixels_versioning_ru-md)
## 环境
必备要求:
-+ C# 7.3 的最低版本;
+* 最低 C# 版本:7.3。
可选要求:
-+ 支持NativeAOT;
-+ 使用 C# 的游戏引擎:Unity、Godot、MonoGame等。
+* 支持 NativeAOT;
+* 使用 C# 的游戏引擎:Unity、Godot、MonoGame 等。
-已测试:
-+ **Unity:** 最低版本 2020.1.0;
+已测试:
+* **Unity:** 最低版本 2021.2.0。
## 为Unity安装
> 还建议安装[Unity引擎集成](https://github.com/DCFApixels/DragonECS-Unity)扩展。
@@ -108,14 +108,32 @@ https://github.com/DCFApixels/DragonECS.git
* ### 作为源代码
框架也可以通过复制源代码添加到项目中。
-
+
+# 扩展
+* 集成:
+ * [Unity](https://github.com/DCFApixels/DragonECS-Unity)
+ * [Godot](https://gitlab.com/InauniusOwn/Libraries/DraGodot)
+* 包:
+ * [自动依赖注入](https://github.com/DCFApixels/DragonECS-AutoInjections)
+ * [经典C#多线程](https://github.com/DCFApixels/DragonECS-ClassicThreads)
+ * [Recursivity](https://github.com/DCFApixels/DragonECS-Recursivity)
+ * [Hybrid](https://github.com/DCFApixels/DragonECS-Hybrid)
+ * [Graphs](https://github.com/DCFApixels/DragonECS-Graphs)
+* 工具:
+ * [简单语法](https://gist.github.com/DCFApixels/d7bfbfb8cb70d141deff00be24f28ff0)
+ * [EcsRefPool](https://gist.github.com/DCFApixels/73e392ccabdd98b3d4a517017d8a3f22)
+ * [计时器](https://gist.github.com/DCFApixels/71a416275660c465ece76242290400df)
+ * [单帧组件](https://gist.github.com/DCFApixels/46d512dbcf96c115b94c3af502461f60)
+ * [IDE代码模板](https://gist.github.com/ctzcs/0ba948b0e53aa41fe1c87796a401660b) 和 [Unity 模板](https://gist.github.com/ctzcs/d4c7730cf6cd984fe6f9e0e3f108a0f1)
+> *你的扩展?如果你正在开发 DragonECS 的扩展,可以[在此处发布](#反馈).
+
# 基础概念
## 实体
-**实体**是附加数据的基础。它们以标识符的形式实现,有两种类型:
-* `int` - 是在单个更新中使用的一次性标识符。不建议存储`int`标识符,而应使用 `entlong`;
-* `entlong` - 是一个长期标识符,包含一整套用于明确识别的信息;
-``` c#
+**实体**是附加数据的基础。有两种用于引用实体的标识符:
+* `int` - 短期标识符,仅在单次更新(tick)内有效。不建议用于长期存储;
+* `entlong` - 长期标识符,包含一个世代标记(generation tag),使其在实体的整个生命周期内保持唯一。适合长期保存和存储使用;
+```c#
// 在世界中创建一个新实体。
int entityID = _world.NewEntity();
@@ -132,7 +150,7 @@ int newEntityID = _world.CloneEntity(entityID);
entlong使用
-``` c#
+```c#
// int 转换为 entlong。
entlong entity = _world.GetEntityLong(entityID);
// 或者
@@ -220,7 +238,7 @@ class SomeSystem : IEcsRun, IEcsPipelineMember
### 依赖注入
框架具有向系统注入依赖的功能。这是一个与管线初始化一起运行的流程,并注入传递给Builder的数据。
> 内置依赖注入的使用是可选的。
-``` c#
+```c#
class SomeDataA { /* ... */ }
class SomeDataB : SomeDataA { /* ... */ }
@@ -251,9 +269,15 @@ class SomeSystem : IEcsInject, IEcsRun
}
```
+静态标记的含义:
+* `Inc` — 组件必须存在(包含条件)并缓存该池。
+* `Exc` — 组件不得存在(排除条件)并缓存该池。
+* `Opt` — 组件可以存在,但不影响过滤(仅缓存池以便访问)。
+* `Any` — 至少要存在被 `Any` 标记的组件之一;同时缓存该池。
+
### 模块
实现一个共同特性的系统组可以组合成模块,模块也可以简单地添加到管线中。
-``` c#
+```c#
using DCFApixels.DragonECS;
class Module1 : IEcsModule
{
@@ -290,11 +314,11 @@ EcsPipeline pipeline = EcsPipeline.New()
.BuildAndInit();
```
嵌入层按以下顺序排列:
-* `EcsConst.PRE_BEGIN_LAYER`
-* `EcsConst.BEGIN_LAYER`
-* `EcsConst.BASIC_LAYER`(默认情况下,系统添加到此层)
-* `EcsConst.END_LAYER`
-* `EcsConst.POST_END_LAYER`
+* `EcsConsts.PRE_BEGIN_LAYER`
+* `EcsConsts.BEGIN_LAYER`
+* `EcsConsts.BASIC_LAYER`(默认情况下,系统添加到此层)
+* `EcsConsts.END_LAYER`
+* `EcsConsts.POST_END_LAYER`
#### 排序顺序
在同一层内,可以使用 `int` 类型的排序值来排序系统。默认情况下,系统的排序值为 `sortOrder = 0`。
```c#
@@ -322,7 +346,7 @@ EcsPipeline pipeline = EcsPipeline.New()
用户流程
-Для добавления нового процесса создайте интерфейс наследованный от `IEcsProcess` и создайте раннер для него. Раннер это класс реализующий интерфейс запускаемого процесса и наследуемый от `EcsRunner`. Пример:
+要添加新的流程,请创建一个继承自 `IEcsProcess` 的接口,并为其创建一个 Runner。Runner 是一个实现该流程接口并继承自 `EcsRunner` 的类。示例:
``` c#
// 流程接口。
interface IDoSomethingProcess : IEcsProcess
@@ -347,10 +371,10 @@ _pipeline = EcsPipeline.New()
.BuildAndInit();
// 如果启动器已经添加,运行它。
-_pipeline.GetRunner.Do()
+_pipeline.GetRunner().Do();
// 如果启动器尚未添加,使用 GetRunnerInstance 将其添加并运行
-_pipeline.GetRunnerInstance.Do()
+_pipeline.GetRunnerInstance().Do();
```
@@ -437,7 +461,7 @@ poses.Del(entityID);
> 可以实现用户池。稍后将介绍这一功能。
## 掩码
-用于根据组件的存在与否来过滤实体。
+用于根据组件的存在与否来过滤实体。通常掩码不单独使用,而是作为 `EcsAspect` 的一部分,用于查询时过滤实体。
``` c#
// 创建一个掩码,检查实体是否具有组件
// SomeCmp1 和 SomeCmp2,但没有组件 SomeCmp3。
@@ -472,7 +496,11 @@ EcsMask mask = _staticMask.ToMask(_world);
## 方面
-这些是继承自 EcsAspect 的用户类,用于与实体进行交互。方面同时充当池的缓存和实体组件的过滤掩码。可以把方面视为系统处理哪些实体的描述。
+方面是继承自 `EcsAspect` 的用户自定义类,用于描述系统要处理的一组组件。方面同时承担两个职责:
+- 掩码 — 初始化并保存一个 `EcsMask`,使其可在查询中用于过滤实体。
+- 池缓存 — 提供对组件池的快速访问。
+
+简而言之,方面是描述“我处理哪些实体以及如何访问它们的组件”的便捷方式。
简化语法:
``` c#
@@ -503,9 +531,9 @@ class Aspect : EcsAspect
public EcsPool velocities;
protected override void Init(Builder b)
{
- poses = b.Include();
- velocities = b.Include();
- b.Exclude();
+ poses = b.Inc();
+ velocities = b.Inc();
+ b.Exc();
}
}
```
@@ -529,13 +557,13 @@ class Aspect : EcsAspect
otherAspect1 = b.Combine(1);
// 即使对 OtherAspect1 调用 Combine 方法更早,Aspect 会首先与 OtherAspect2 进行组合,因为默认情况下 order = 0。
otherAspect2 = b.Combine();
- // 如果 OtherAspect1 或 OtherAspect2 中有 b.Exclude() 的限制条件,这里将被替换为 b.Include()。
- poses = b.Include();
+ // 如果 OtherAspect1 或 OtherAspect2 中有 b.Exc() 的限制条件,这里将被替换为 b.Inc().
+ poses = b.Inc();
}
}
```
如果组合的方面存在冲突的限制条件,则新的限制条件将替换先前添加的限制条件。根方面的限制条件始终会替换添加的方面中的限制条件。限制条件组合的视觉示例:
-| | cmp1 | cmp2 | cmp3 | cmp4 | cmp5 | разрешение конфликтных ограничений|
+| | cmp1 | cmp2 | cmp3 | cmp4 | cmp5 | 冲突限制的解析 |
| :--- | :--- | :--- | :--- | :--- | :--- |:--- |
| OtherAspect2 | :heavy_check_mark: | :x: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_check_mark: | |
| OtherAspect1 | :heavy_minus_sign: | :heavy_check_mark: | :heavy_minus_sign: | :x: | :heavy_minus_sign: | 对于 `cmp2` 将选择 :heavy_check_mark: |
@@ -978,6 +1006,23 @@ public struct WorldComponent : IEcsWorldComponent
## Released games:
-# 扩展
-* Packages:
- * [Unity集成](https://github.com/DCFApixels/DragonECS-Unity)
- * [自动依赖注入](https://github.com/DCFApixels/DragonECS-AutoInjections)
- * [经典C#多线程](https://github.com/DCFApixels/DragonECS-ClassicThreads)
- * [Recursivity](https://github.com/DCFApixels/DragonECS-Recursivity)
- * [Hybrid](https://github.com/DCFApixels/DragonECS-Hybrid)
- * [Graphs](https://github.com/DCFApixels/DragonECS-Graphs)
-* Utilities:
- * [简单语法](https://gist.github.com/DCFApixels/d7bfbfb8cb70d141deff00be24f28ff0)
- * [单帧组件](https://gist.github.com/DCFApixels/46d512dbcf96c115b94c3af502461f60)
- * [IDE代码模板](https://gist.github.com/ctzcs/0ba948b0e53aa41fe1c87796a401660b) и [Unity代码模板](https://gist.github.com/ctzcs/d4c7730cf6cd984fe6f9e0e3f108a0f1)
-
-> *你的扩展?如果你正在开发 DragonECS 的扩展,可以[在此处发布](#反馈).
-
-
# FAQ
-## 'ReadOnlySpan<>' could not be found
-在Unity 2020.1.x版本中,控制台可能会出现以下错误:
-```
-The type or namespace name 'ReadOnlySpan<>' could not be found (are you missing a using directive or an assembly reference?)
-```
-要解决这个问题,需要在`Project Settings/Player/Other Settings/Scripting Define Symbols`中添加`ENABLE_DUMMY_SPAN`指令.
+
+## 如何启用/禁用系统?
+直接——不能。
+
+通常当游戏的整体状态发生变化时,会需要启用或禁用系统;有时需要切换一组系统。从概念上讲,这可以视为流程(process)的变更。这里有两种解决方案:
+
+- 如果流程变更是全局性的,可以创建一个新的 `EcsPipeline`,并在引擎的更新循环中运行相应的管线(pipeline)。
+- 将 `IEcsRun` 拆分为多个流程,并在引擎更新循环中运行所需的流程。为此,创建一个新的流程接口,为其实现一个 Runner,并通过 `EcsPipeline.GetRunner()` 获取该 Runner。
+
+## 建议清单: [DragonECS-Vault](https://github.com/DCFApixels/DragonECS-Vault)
# 反馈
diff --git a/README.md b/README.md
index c3f9193..f6c1583 100644
--- a/README.md
+++ b/README.md
@@ -22,26 +22,26 @@
-
+ 
Русский
|
-
+ 
English
|
-
+ 
中文
|
-
+
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).
@@ -54,6 +54,7 @@ The [ECS](https://en.wikipedia.org/wiki/Entity_component_system) Framework aims
## Table of Contents
- [Installation](#installation)
+- [Extensions](#extensions)
- [Basic Concepts](#basic-concepts)
- [Entity](#entity)
- [Component](#component)
@@ -91,14 +92,14 @@ The [ECS](https://en.wikipedia.org/wiki/Entity_component_system) Framework aims
Versioning semantics - [Open](https://gist.github.com/DCFApixels/e53281d4628b19fe5278f3e77a7da9e8#file-dcfapixels_versioning_ru-md)
## Environment
Requirements:
-+ Minimum version of C# 7.3;
-
+* Minimum C# version: 7.3.
+
Optional:
-+ Support for NativeAOT
-+ Game engines with C#: Unity, Godot, MonoGame, etc.
-
+* Support for NativeAOT
+* Game engines with C#: Unity, Godot, MonoGame, etc.
+
Tested with:
-+ **Unity:** Minimum version 2020.1.0;
+* **Unity:** Minimum version 2021.2.0.
## Unity Installation
* ### Unity Package
@@ -109,14 +110,32 @@ https://github.com/DCFApixels/DragonECS.git
* ### Source Code
The framework can also be added to the project as source code.
-
+
+# Extensions
+* Integrations:
+ * [Unity](https://github.com/DCFApixels/DragonECS-Unity)
+ * [Godot](https://gitlab.com/InauniusOwn/Libraries/DraGodot)
+* Packages:
+ * [Dependency autoinjections](https://github.com/DCFApixels/DragonECS-AutoInjections)
+ * [Classic C# multithreading](https://github.com/DCFApixels/DragonECS-ClassicThreads)
+ * [Recursivity](https://github.com/DCFApixels/DragonECS-Recursivity)
+ * [Hybrid](https://github.com/DCFApixels/DragonECS-Hybrid)
+ * [Graphs](https://github.com/DCFApixels/DragonECS-Graphs)
+* Utilities:
+ * [Simple syntax](https://gist.github.com/DCFApixels/d7bfbfb8cb70d141deff00be24f28ff0)
+ * [EcsRefPool](https://gist.github.com/DCFApixels/73e392ccabdd98b3d4a517017d8a3f22)
+ * [Timers](https://gist.github.com/DCFApixels/71a416275660c465ece76242290400df)
+ * [One-Frame Components](https://gist.github.com/DCFApixels/46d512dbcf96c115b94c3af502461f60)
+ * [Code Templates for IDE](https://gist.github.com/ctzcs/0ba948b0e53aa41fe1c87796a401660b) and [for Unity](https://gist.github.com/ctzcs/d4c7730cf6cd984fe6f9e0e3f108a0f1)
+> *Your extension? If you are developing an extension for DragonECS, you can share it [here](#feedback).
+
# Basic Concepts
## Entity
-Сontainer for components. They are implemented as identifiers, of which there are two types:
-* `int` - a short-term identifier used within a single tick. Storing `int` identifiers is not recommended, use `entlong` instead;
-* `entlong` - long-term identifier, contains a full set of information for unique identification;
-``` c#
+Container for components. There are two identifier types used to reference entities:
+* `int` - short-lived identifier, valid within a single tick. Not recommended for long-term storage;
+* `entlong` - long-term identifier that includes a generation tag, which makes it unique across entity lifetimes. Suitable for storing and long-term usage.
+```c#
// Creating a new entity in the world.
int entityID = _world.NewEntity();
@@ -133,7 +152,7 @@ int newEntityID = _world.CloneEntity(entityID);
Working with entlong
-``` c#
+```c#
// Convert int to entlong.
entlong entity = _world.GetEntityLong(entityID);
// or
@@ -222,7 +241,7 @@ class SomeSystem : IEcsRun, IEcsPipelineMember
### Dependency Injection
The framework implements dependency injection for systems. This process begins during pipeline initialization and injects data passed to the Builder.
> Using built-in dependency injection is optional.
-``` c#
+```c#
class SomeDataA { /* ... */ }
class SomeDataB : SomeDataA { /* ... */ }
@@ -257,7 +276,7 @@ class SomeSystem : IEcsInject, IEcsRun
### Modules
Groups of systems that implement a common feature can be grouped into modules and easily added to the Pipeline.
-``` c#
+```c#
using DCFApixels.DragonECS;
class Module1 : IEcsModule
{
@@ -294,11 +313,11 @@ EcsPipeline pipeline = EcsPipeline.New()
.BuildAndInit();
```
The built-in layers are arranged in the following order:
-* `EcsConst.PRE_BEGIN_LAYER`
-* `EcsConst.BEGIN_LAYER`
-* `EcsConst.BASIC_LAYER` (Systems are added here if no layer is specified during addition)
-* `EcsConst.END_LAYER`
-* `EcsConst.POST_END_LAYER`
+* `EcsConsts.PRE_BEGIN_LAYER`
+* `EcsConsts.BEGIN_LAYER`
+* `EcsConsts.BASIC_LAYER` (Systems are added here if no layer is specified during addition)
+* `EcsConsts.END_LAYER`
+* `EcsConsts.POST_END_LAYER`
#### Sorting Order
The sort order int value is used to sort systems within a layer. By default, systems are added with `sortOrder = 0`.
@@ -352,10 +371,10 @@ _pipeline = EcsPipeline.New()
.BuildAndInit();
// Running the runner if it was added
-_pipeline.GetRunner.Do()
+_pipeline.GetRunner().Do();
// or if the runner was not added (calling GetRunnerInstance will also add the runner to the pipeline).
-_pipeline.GetRunnerInstance.Do()
+_pipeline.GetRunnerInstance().Do();
```
@@ -444,7 +463,7 @@ poses.Del(entityID);
> It is possible to implement a user pool. This feature will be described shortly.
## Mask
-Used to filter entities by the presence or absence of components.
+Used to filter entities by the presence or absence of components. Usually masks are not used standalone, they are part of `EcsAspect` and used by queries to filter entities.
``` c#
// Creating a mask that checks if entities have components
// SomeCmp1 and SomeCmp2, but do not have component SomeCmp3.
@@ -479,7 +498,11 @@ EcsMask mask = _staticMask.ToMask(_world);
## Aspect
-These are custom classes inherited from `EcsAspect` and used to interact with entities. Aspects are both a pool cache and a component mask for filtering entities. You can think of aspects as a description of what entities the system is working with.
+These are user-defined classes that inherit from `EcsAspect` and describe sets of components a system works with. An aspect serves two purposes:
+- Mask — initializes and holds an `EcsMask`, so it can be used in queries to filter entities.
+- Pool cache — provides fast access to component pools.
+
+In short, an aspect is a convenient way to declare "which entities I work with and how to access their components."
Simplified syntax:
``` c#
@@ -500,6 +523,13 @@ class Aspect : EcsAspect
}
```
+Purpose of the static markers:
+* `Inc` — component must be present (inclusive) and caches the pool.
+* `Exc` — component must NOT be present (exclusive) and caches the pool.
+* `Opt` — component may be present, but does not affect filtering (only caches the pool for access).
+* `Any` — at least one of the components marked with `Any` must be present; caches the pool.
+
+
Explicit syntax (the result is identical to the example above):
``` c#
using DCFApixels.DragonECS;
@@ -510,9 +540,9 @@ class Aspect : EcsAspect
public EcsPool velocities;
protected override void Init(Builder b)
{
- poses = b.Include();
- velocities = b.Include();
- b.Exclude();
+ poses = b.Inc();
+ velocities = b.Inc();
+ b.Exc();
}
}
```
@@ -536,17 +566,17 @@ class Aspect : EcsAspect
otherAspect1 = b.Combine(1);
// Although Combine was called earlier for OtherAspect1, it will first combine with OtherAspect2 because the default order is 0.
otherAspect2 = b.Combine();
- // If b.Exclude() was specified in OtherAspect1 or OtherAspect2, it will be replaced with b.Include() here.
- poses = b.Include();
+ // If b.Exc() was specified in OtherAspect1 or OtherAspect2, it will be replaced with b.Inc() here.
+ poses = b.Inc();
}
}
```
If there are conflicting constraints between the combined aspects, the new constraints will replace those added earlier. Constraints from the root aspect always replace constraints from added aspects. Here's a visual example of constraint combination:
-| | cmp1 | cmp2 | cmp3 | cmp4 | cmp5 | разрешение конфликтных ограничений|
+| | cmp1 | cmp2 | cmp3 | cmp4 | cmp5 | Conflict resolution |
| :--- | :--- | :--- | :--- | :--- | :--- |:--- |
| OtherAspect2 | :heavy_check_mark: | :x: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_check_mark: | |
-| OtherAspect1 | :heavy_minus_sign: | :heavy_check_mark: | :heavy_minus_sign: | :x: | :heavy_minus_sign: | For `cmp2` will be chosen. :heavy_check_mark: |
-| Aspect | :x: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_check_mark: | For `cmp1` will be chosen. :x: |
+| OtherAspect1 | :heavy_minus_sign: | :heavy_check_mark: | :heavy_minus_sign: | :x: | :heavy_minus_sign: | For `cmp2`, :heavy_check_mark: will be chosen. |
+| Aspect | :x: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_check_mark: | For `cmp1`, :x: will be chosen. |
| Final Constraints | :x: | :heavy_check_mark: | :heavy_minus_sign: | :x: | :heavy_check_mark: | |
@@ -984,6 +1014,23 @@ public struct WorldComponent : IEcsWorldComponent
## Released games:
-# Extensions
-* Packages:
- * [Unity integration](https://github.com/DCFApixels/DragonECS-Unity)
- * [Dependency autoinjections](https://github.com/DCFApixels/DragonECS-AutoInjections)
- * [Classic C# multithreading](https://github.com/DCFApixels/DragonECS-ClassicThreads)
- * [Recursivity](https://github.com/DCFApixels/DragonECS-Recursivity)
- * [Hybrid](https://github.com/DCFApixels/DragonECS-Hybrid)
- * [Graphs](https://github.com/DCFApixels/DragonECS-Graphs)
-* Utilities:
- * [Simple syntax](https://gist.github.com/DCFApixels/d7bfbfb8cb70d141deff00be24f28ff0)
- * [One-Frame Components](https://gist.github.com/DCFApixels/46d512dbcf96c115b94c3af502461f60)
- * [Code Templates for IDE](https://gist.github.com/ctzcs/0ba948b0e53aa41fe1c87796a401660b) and [for Unity](https://gist.github.com/ctzcs/d4c7730cf6cd984fe6f9e0e3f108a0f1)
-> *Your extension? If you are developing an extension for DragonECS, you can share it [here](#feedback).
-
-
# FAQ
-## 'ReadOnlySpan<>' could not be found
-In Unity 2020.1.x, you may encounter this error in the console:
-```
-The type or namespace name 'ReadOnlySpan<>' could not be found (are you missing a using directive or an assembly reference?)
-```
-To fix this, add the define symbol `ENABLE_DUMMY_SPAN` to `Project Settings/Player/Other Settings/Scripting Define Symbols`.
+## How to enable/disable systems?
+Directly — you can't.
+
+The need to enable or disable systems usually appears when the overall game state changes; this may also mean switching a group of systems. Conceptually this is a change of processes. There are two solutions:
+
+- If the process changes are global, create a new `EcsPipeline` and run the appropriate pipeline in the engine update loop.
+- Split `IEcsRun` into multiple processes and run the desired process in the engine update loop. To do this create a new process interface, implement a runner for it, and obtain the runner via `EcsPipeline.GetRunner()`.
+
+## Recommendations list: [DragonECS-Vault](https://github.com/DCFApixels/DragonECS-Vault)
# Feedback