entity system architecture with unity @unite europe 2015

51
Entity system architecture with Unity

Upload: maxim-zaks

Post on 06-Aug-2015

140 views

Category:

Education


6 download

TRANSCRIPT

Entity system architecture

with Unity

Maxim Zaks@icex33 | github.com/mzaks

Simon Schmid@s_schmid | github.com/sschmid

Unity pain points• Testability

• Code sharing

• Co-dependent logic

• Querying

• Deleting code

Testability

Code sharing

Co-dependent logic

Co-dependent logic

Co-dependent logic

Querying

Deleting code

EntitasMatch One Demo

PositionComponent

using Entitas;

public class PositionComponent : IComponent{ public int x; public int y;}

GameBoardElementComponent

using Entitas;

public class GameBoardElementComponent : IComponent {}

Entity• Add

• Replace

• Remove

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• Create Entity

• Destroy Entity

• Get all Entities

• Get Group

GroupPerformance optimization for querying

Matcher is a filter description

Get Group

_pool.GetGroup( Matcher.AllOf( Matcher.GameBoardElement, Matcher.Position ));

+------------------+ | Pool | |------------------| | 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 | +------------------+ +-----------+ +-----------+ | | | +-------------+ | | e | Groups | | e e | +---> | +------------+ | e | | | | e | e | e | +--------|----+ e | | e | | e e | +------------+

Behaviour

System• Start / Execute

• No State

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

+------------+ +------------+ +------------+ +------------+| | | | | | | || System | +---> | System | +---> | System | +---> | System || | | | | | | |+------------+ +------------+ +------------+ +------------+

return new Systems() .Add(pool.CreateSystem <GameBoardSystem> ()) .Add(pool.CreateSystem <CreateGameBoardCacheSystem> ()) .Add(pool.CreateSystem <FallSystem> ()) .Add(pool.CreateSystem <FillSystem> ())

.Add(pool.CreateSystem <ProcessInputSystem> ())

.Add(pool.CreateSystem <RemoveViewSystem> ()) .Add(pool.CreateSystem <AddViewSystem> ()) .Add(pool.CreateSystem <RenderPositionSystem> ())

.Add(pool.CreateSystem <DestroySystem> ()) .Add(pool.CreateSystem <ScoreSystem> ());

Reacting to changes in a Group• On Entity added

• 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 System• Executed only when entities in group have changed

Render Position System

public class RenderPositionSystem : IReactiveSystem { public IMatcher GetTriggeringMatcher() { return Matcher.AllOf(Matcher.View, Matcher.Position); }

public GroupEventType GetEventType() { 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

EntityStore components inDictionary vs Array

ComparisonDictionary

e.AddComponent(new PositionComponent());

var component = e.GetComponent<PositionComponent>();

Array

e.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

How does it work?

Visual Debugging Demo

Entitas isopen source

github.com/sschmid/Entitas-CSharp

Recap

Unity pain points• Testability

• Code sharing

• Co-dependent logic

• Querying

• Deleting code

Advantages• Straightforward to achieve Determinism and therefore

Replay

• Simulation Speed (2x, 4x)

• Headless Simulation, just remove systems which rely on GameObjects (render systems)

• Save Game (Serialization / Deserialization) send data to backend on change

• For us it replaced all OO Design Patterns

Q&Atinyurl.com/entitas