Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Entity System Architecture with Unity - Unity User Group Berlin

1,095 views

Published on

Entity System Architecture with Unity - Unity User Group Berlin
Entitas - open source Entity Component System for C# and Unity: https://github.com/sschmid/Entitas-CSharp

Published in: Software
  • Be the first to comment

Entity System Architecture with Unity - Unity User Group Berlin

  1. 1. Entity system architecture with Unity
  2. 2. Maxim Zaks | @icex33 | github.com/mzaks Simon Schmid | @s_schmid | github.com/sschmid
  3. 3. Wooga
  4. 4. Unity pain points 4 Testability 4 Code sharing 4 Co-dependent logic 4 Querying 4 Deleting code
  5. 5. Testability
  6. 6. Code sharing
  7. 7. Co-dependent logic
  8. 8. Co-dependent logic
  9. 9. Co-dependent logic
  10. 10. Querying
  11. 11. Deleting code
  12. 12. Entitas Match One Demo
  13. 13. Components are just data 4 no Methods, no Start(), no Update() 4 no inheritance +-----------+ | Component | |-----------| | Data | +-----------+
  14. 14. PositionComponent using Entitas; public class PositionComponent : IComponent { public int x; public int y; }
  15. 15. GameBoardElementComponent using Entitas; public class GameBoardElementComponent : IComponent { }
  16. 16. Entity is a container for components +-----------+ | Entity | |-----------| | Component | | | | Component | | | | Component | +-----------+
  17. 17. Entity 4 Add Components 4 Replace Components 4 Remove Components
  18. 18. 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); }
  19. 19. Pool contains all entities +------------------+ | Pool | |------------------| | e e | | e e | | e e | | e e e | | e e | | e e | | e e e | | e e e | +------------------+
  20. 20. Pool 4 Create Entity 4 Destroy Entity 4 Get all Entities 4 Get Group
  21. 21. 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 | +------------+
  22. 22. Get Group from pool _pool.GetGroup( Matcher.AllOf( Matcher.GameBoardElement, Matcher.Position ) );
  23. 23. +------------------+ | 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 | +------------+
  24. 24. Behaviour
  25. 25. System 4 Start / Execute 4 No State!!!
  26. 26. +------------------+ +-----------------------------+ | 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 | | | +------------+ | +-----------------------------+
  27. 27. 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); } }
  28. 28. Chain of Responsibility | | |-------------------------------- Game Loop --------------------------------| | | +------------+ +------------+ +------------+ +------------+ | | | | | | | | | System | +---> | System | +---> | System | +---> | System | | | | | | | | | +------------+ +------------+ +------------+ +------------+
  29. 29. 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 ());
  30. 30. Reacting to changes in a Group 4 On Entity added 4 On Entity removed
  31. 31. 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; }
  32. 32. Reactive System 4 Executed only when entities in a group have changed 4 Aggregate and process changes
  33. 33. 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); } } }
  34. 34. Optimizations
  35. 35. Components mutable vs immutable
  36. 36. Entity Dictionary vs Array
  37. 37. Dictionary e.AddComponent(new PositionComponent()); var component = e.GetComponent<PositionComponent>(); Array e.AddComponent(new PositionComponent(), 5); var component = (PositionComponent)e.GetComponent(5);
  38. 38. Code Generator
  39. 39. 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);
  40. 40. After Code Generation e.ReplacePosition(10, 10);
  41. 41. Code Generator Demo
  42. 42. 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;
  43. 43. Visual Debugging Demo
  44. 44. Entitas is open sourcegithub.com/sschmid/Entitas-CSharp
  45. 45. Recap
  46. 46. Unity pain points 4 Testability 4 Code sharing 4 Co-dependent logic 4 Querying 4 Deleting code
  47. 47. 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
  48. 48. Q&AMaxim Zaks | @icex33 | github.com/mzaks Simon Schmid | @s_schmid | github.com/sschmid tinyurl.com/entitas

×