UNITE Europe 2015 + Unity User Group Presentation
Unity incorporates the component based architecture in a seamless manner. But for some games, a more data driven approach (entity system architecture) fits better. In this talk, Maxim Zaks & Simon Schmid (Wooga) show why entity system architecture fits and how you can use Entitas-CSharp in your own Unity project.
21. Create Blocker Entity
public static Entity CreateBlocker(this Pool pool, int x, int y)
{
return pool.CreateEntity()
.IsGameBoardElement(true)
.AddPosition(x, y)
.AddResource(Res.Blocker);
}
22. Pool contains all entities
+------------------+
| Pool |
|------------------|
| e e |
| e e |
| e e |
| e e e |
| e e |
| e e |
| e e e |
| e e e |
+------------------+
24. Groups are subsets of entities
4 Performance optimization for querying
4 Matcher is a filter description
+-------------+ Groups:
| e | Subsets of entities in the pool
| e e | for blazing fast querying
| +------------+
| e | | |
| e | e | e |
+--------|----+ e |
| e |
| e e |
+------------+
25. Get Group from pool
_pool.GetGroup(
Matcher.AllOf(
Matcher.GameBoardElement,
Matcher.Position
)
);
26. +------------------+
| Pool | Entitas in a nutshell
|------------------|
| e e | +-----------+
| e e---|----> | Entity |
| e e | |-----------|
| e e e | | Component |
| e e | | | +-----------+
| e e | | Component-|----> | Component |
| e e e | | | |-----------|
| e e e | | Component | | Data |
+------------------+ +-----------+ +-----------+
|
|
| +-------------+ Groups:
| | e | Subsets of entities in the pool
| | e e | for blazing fast querying
+---> | +------------+
| e | | |
| e | e | e |
+--------|----+ e |
| e |
| e e |
+------------+
29. +------------------+ +-----------------------------+
| Pool | | System |
|------------------| |-----------------------------|
| e e | | - Execute |
| e e | | |
| e e | | +-------------+ |
| e e e | | | e | Groups |
| e e |+----|->| e e | |
| e e | | | +------------+ |
| e e e | | | e | | | |
| e e e | | | e | e | e | |
+------------------+ | +--------|----+ e | |
| | e | |
| | e e | |
| +------------+ |
+-----------------------------+
30. MoveSystem
public void Execute() {
var movables = _pool.GetGroup(
Matcher.AllOf(
Matcher.Move,
Matcher.Position
));
foreach (var e in movables.GetEntities()) {
var move = e.move;
var pos = e.position;
e.ReplacePosition(pos.x, pos.y + move.speed, pos.z);
}
}
31. Chain of Responsibility
| |
|-------------------------------- Game Loop --------------------------------|
| |
+------------+ +------------+ +------------+ +------------+
| | | | | | | |
| System | +---> | System | +---> | System | +---> | System |
| | | | | | | |
+------------+ +------------+ +------------+ +------------+
36. Render Position System
public class RenderPositionSystem : IReactiveSystem {
public IMatcher trigger { get { return Matcher.AllOf(Matcher.Position, Matcher.View); } }
public GroupEventType eventType { get { return GroupEventType.OnEntityAdded; } }
public void Execute(Entity[] entities) {
foreach (var e in entities) {
var pos = e.position;
e.view.gameObject.transform.position = new Vector3(pos.x, pos.y);
}
}
}
49. var pool = Pools.pool;
var e = pool.CreateEntity();
e.AddPosition(1, 2, 3);
e.ReplacePosition(4, 5, 6);
e.RemovePosition();
var posX = e.position.x;
var hasPos = e.hasPosition;
e.isMovable = true;
e.isMovable = false;
var isMovable = e.isMovable;
55. Advantages
4 Straightforward to achieve Determinism and
therefore Replay
4 Simulation Speed (2x, 4x)
4 Headless Simulation, just remove systems which rely
on GameObjects (render systems)
4 Save Game (Serialization / Deserialization) send
data to backend on change