20180312
ECS programming ideas
This programming idea has been proposed a long time ago, and ECS is the abbreviation of Entity, Component, and System.
- Entity is an instance, as a carrier for carrying components, and an entity for maintaining objects in the framework.
- Component only contains data, and having this component has this function.
- System acts as logical maintenance, maintaining the corresponding components to perform related operations.
Compared with traditional OOP, ECS pays more attention to components, and additional components have functions.
C# is an object-oriented language, which supports object-oriented programming ideas from the language level: integrated encapsulation and polymorphism.
-
Object Oriented: What am I, I have properties, I have methods, I want to inherit and then rewrite it to be unique.
-
Component-oriented: what do I have, I have components and I have this function, and I make up entities from many components.
According to the idea of ECS, the function is divided into components, and then these small components are combined to form an object with the required functions. In fact, Unity is also this implementation idea, but it is a collection of component attributes and logic.
Recently I read ECS programming ideas, read Entitas logic, and wrote a small demo. I feel:
There is no best programming idea/framework, only more suitable, maybe A frame is suitable for RPG games, B frame is more suitable for FPS games.
-
Timing of Entity
Logic that controls timing is often encountered in development. For example, an Entity must be executed after another Entity logic is completed. Of course, timing execution can be controlled by adding component identifiers, but if there are a large number of such logics, a lot of corresponding logic will be added. components as identifiers.
-
System Timing
It is also possible to add Component as a control identifier as a filter condition. System A needs to be completed after system B, before system C is started, and system D is suspended. Performance, end,) too many states, one frame/framing maintenance, it is estimated that it will be messy.
-
System is more suitable for maintaining a set of Entity
-
For example, FPS games and MOBA games are suitable for splitting with ECS ideas. Each player's role functions are equivalent (all characters, all moving and fighting), and the skills and guns of different characters are split separately.
-
If it is a large-scale RPG game, the status and actions of each martial character, lobby NPC, mall merchant, and enemy characters are different. Of course, this kind of ECS can be realized. Each function is divided into small components, and the corresponding System class is created for maintenance, but In the final analysis, a System only maintains a component on an Entity after traversing and filtering. Because the role function is unique, this component will not be used in combination with other Entity in the future.
-
-
Functional decoupling
Decoupling between functions, the corresponding components and systems only care about their own functions and will not affect other functions.
-
refactor
Inconvenient to refactor
-
data maintenance
The data is distributed to the corresponding components, for example, the server sends a latest data, and the attributes of the corresponding components need to be maintained one by one, and the same is true for data collection.
-
Client server shared code
After the client splits the presentation components, it only contains pure logic functions.
-
Data layer presentation layer separation
It is maintained in different components and systems, and there is no need to split the presentation logic like oop.
-
Easy to expand
If designed properly, new Entity can be composed by existing components. 1- Performance
Data exists linearly in memory, and Entity is reused.
ECS Framework: Entitas
There are many frameworks based on ECS, Entitas is one of them.
The official ECS will also be launched in the 2018.1 beta version.
According to the wiki, it is easy to build a project and run the project, but some also require the developer's attention, such as Component as an identifier or as a data storage; Component generates code after changing the type or deleting the field and generates an error, Group/Feature/Unit use etc.
Regarding code generation, it provides two versions:
- Free version
- Paid version
The free version generates code based on reflection, and it needs to run without compilation errors; the paid version does not need it, and it can generate code even if there is a code error.
The code for your own extension can be divided into two parts:
- Components
- Other code (System, Service... and other logic)
The advantage of this is that when regenerating code, it is convenient to remove these two directories from the project (or StreamingAssets), generate the base code, then move back to the Component code, then generate the component code, and then move back to other code.
Entitas Practice
The simplest output hello world
Source code: https://github.com/hiramtan/test/tree/Entitas_Example_HelloWorld
Create a Component:
public class HelloWorldComponent : IComponent
{
public string s;
}
After generating the code, create two systems, one for creating entities and attaching components, and the other for outputting logs:
public class CreatSystem : IInitializeSystem
{
private Contexts _contexts;
public CreatSystem(Contexts contexts)
{
_contexts = contexts;
}
public void Initialize()
{
var e = _contexts.game.CreateEntity();
e.AddHelloWorld("hello world");
}
}
public class HelloWorldSystem : ReactiveSystem<GameEntity>
{
private Contexts _contexts;
public HelloWorldSystem(Contexts contexts) : base(contexts.game){
}
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
return context.CreateCollector(GameMatcher.HelloWorld);
}
protected override bool Filter(GameEntity entity)
{
return entity.hasHelloWorld;
}
protected override void Execute(List<GameEntity> entities)
{
foreach (var e in entities)
{
Debug.Log(e.helloWorld.s);
}
}
}
The above code has implemented the output function, but in order to facilitate the management of the above two systems, we add a RootSystems to manage various systems in the game:
public class RootSystems : Feature
{
public RootSystems(Contexts contexts)
{
Add(new CreatSystem(contexts));
Add(new HelloWorldSystem(contexts));
}
}
All functions are implemented, add an entry method to the unity project and mount it to the scene, Main.cs:
public class Main : MonoBehaviour
{
private RootSystems s;
// Use this for initialization
void Start()
{
s = new RootSystems(Contexts.sharedInstance);
s.Initialize();
}
// Update is called once per frame
void Update()
{
s.Execute();
}
}
Run, output normally, because the output implements a reactive system, it will output when the value changes.
Unity ECS
Today untiy announced its own ECS system in the beta version, Entity, ComponentData, ComponentSystem, with the official introduction of unity, it is bound to be promoted.
Click the link to join the QQ group [83596104]: https://jq.qq.com/?_wv=1027&k=5l6rZEr
References
- https://github.com/sschmid/Entitas-CSharp
- https://blog.codingnow.com/2017/06/overwatch_ecs.html
- http://www.ecsframework.com/
- https://youtu.be/OJmVBo5HGOY
- http://t-machine.org/index.php/category/entity-systems/
- http://www.benmutou.com/archives/2421
- https://www.cnblogs.com/yangrouchuan/p/7436533.html
- http://blog.csdn.net/u012632851/article/details/75370836
- http://blog.csdn.net/langresser_king/article/details/46324977
- http://blog.csdn.net/wuxiaoming1733/article/details/79037812
- http://blog.lmorchard.com/2013/11/27/entity-component-system/
- http://piemaster.net/2011/07/entity-component-primer/
- http://www.richardlord.net/blog/ecs/what-is-an-entity-framework.html
- http://blog.csdn.net/qq992817263/article/details/78155443