Unity User Group Berlin Entitas
-
Upload
simon-schmid -
Category
Software
-
view
384 -
download
0
Transcript of Unity User Group Berlin Entitas
Entity system architecturewith Unity
Maxim Zaks | @icex33 | github.com/mzaksSimon Schmid | @s_schmid | github.com/sschmid
Wooga
Unity pain points4 Testability
4 Code sharing
4 Co-dependent logic
4 Querying
4 Deleting code
Testability
Code sharing
Co-dependent logic
Co-dependent logic
Co-dependent logic
Querying
Deleting code
EntitasMatch One Demo
Components are just data
4 no Methods, no Start(), no Update()
4 no inheritance
+-----------+ | Component | |-----------| | Data | +-----------+
PositionComponent
using Entitas;
public class PositionComponent : IComponent{ public int x; public int y;}
GameBoardElementComponent
using Entitas;
public class GameBoardElementComponent : IComponent{
}
Entity is a container for components
+-----------+ | Entity | |-----------| | Component | | | | Component | | | | Component | +-----------+
Entity4 Add Components
4 Replace Components
4 Remove Components
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);}
Pool contains all entities
+------------------+ | Pool | |------------------| | e e | | e e | | e e | | e e e | | e e | | e e | | e e e | | e e e | +------------------+
Pool4 Create Entity
4 Destroy Entity
4 Get all Entities
4 Get Group
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 | +------------+
Get Group from pool
_pool.GetGroup( Matcher.AllOf( Matcher.GameBoardElement, Matcher.Position ));
+------------------+ | 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 | +------------+
Behaviour
System4 Start / Execute
4 No State!!!
+------------------+ +-----------------------------+ | 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 | | | +------------+ | +-----------------------------+
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); }}
Chain of Responsibility| ||-------------------------------- Game Loop --------------------------------|| |
+------------+ +------------+ +------------+ +------------+| | | | | | | || System | +---> | System | +---> | System | +---> | System || | | | | | | |+------------+ +------------+ +------------+ +------------+
return new Systems() .Add( pool.CreateGameBoardSystem ()) .Add( pool.CreateCreateGameBoardCacheSystem ()) .Add( pool.CreateFallSystem ()) .Add( pool.CreateFillSystem ())
.Add( pool.CreateProcessInputSystem ())
.Add( pool.CreateRemoveViewSystem ()) .Add( pool.CreateAddViewSystem ()) .Add( pool.CreateRenderPositionSystem ())
.Add( pool.CreateDestroySystem ()) .Add( pool.CreateScoreSystem ());
Reacting to changes in a Group4 On Entity added
4 On Entity removed
ScoreLabelController
void Start() { _pool.GetGroup(Matcher.Score).OnEntityAdded += (group, entity) => updateScore(entity.score.value);
updateScore(_pool.score.value);}
void updateScore(int score) { _label.text = "Score " + score;}
Reactive System4 Executed only when entities in a group have changed
4 Aggregate and process changes
Render Position Systempublic 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); } }}
Optimizations
Componentsmutable vs immutable
EntityDictionary vs Array
Dictionarye.AddComponent(new PositionComponent());
var component = e.GetComponent<PositionComponent>();
Arraye.AddComponent(new PositionComponent(), 5);
var component = (PositionComponent)e.GetComponent(5);
Code Generator
Before Code Generation
PositionComponent component;if (e.HasComponent(ComponentIds.Position)) { e.WillRemoveComponent(ComponentIds.Position); component = (PositionComponent)e.GetComponent(ComponentIds.Position);} else { component = new PositionComponent();}component.x = 10;component.y = 10;e.ReplaceComponent(ComponentIds.Position, component);
After Code Generation
e.ReplacePosition(10, 10);
Code Generator Demo
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;
Visual Debugging Demo
Entitas is
open sourcegithub.com/sschmid/Entitas-CSharp
Recap
Unity pain points4 Testability
4 Code sharing
4 Co-dependent logic
4 Querying
4 Deleting code
Advantages4 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
Q&AMaxim Zaks | @icex33 | github.com/mzaks
Simon Schmid | @s_schmid | github.com/sschmid
tinyurl.com/entitas