Search Unity

Separation of Behaviour and Rendering - e.g. Destroyed Entities

Discussion in 'Graphics for ECS' started by TickTakashi, Jun 3, 2018.

  1. TickTakashi

    TickTakashi

    Joined:
    Mar 14, 2013
    Posts:
    31
    Hi, it's me and my board game again.

    I'm looking for tips on the separation of behaviour and rendering in the ECS world. All of my game logic so far is pure data, and now i'm looking at ways to elegantly display that data without having to change the game logic.

    In the old OOP world of Unity's past, i've kept my game logic model in a separate out-of-unity dll, and had the in-unity display logic listen to events fired by the model, updating themselves accordingly.

    However, In ECS, where events are really just short-lived components, this solution isn't really possible without the model knowing about View entities and adding components to them.

    I could attach rendering components the existing entities (Transform, Mesh components, etc), and systems that update the them (e.g. when a piece is moved on the board, LocationViewSystem update it's Transform based on its in data board Location.). However, this doesn't always work well,

    One simple example: i'm looking at the age old problem of displaying corpses - in the game logic, a piece that is "taken" has it's entity destroyed, but I still need to show the piece being destroyed visually, I don't want the game logic to "wait" for the death animation, as that is creating a dependency on the view logic.

    So far, I've come up with a few possible solutions:

    1. Create Event Entities, emitted by the model with data about the model entities that fired them. The view can define systems that iterate over these events and map those to View entities.

    2. Adapt the Model to support joint model-view entities - specifically, don't destroy Piece entities when they are taken, but instead add or remove components to stop those entities from being processed by systems that act on Living entities. For example: by adding a
    Destroyed
    component and
    SubtractiveComponent<Destroyed>
    properties in system groups.

    3. The concept of having separate Worlds for logic and rendering is something that is mentioned briefly in the documentation, but i'm not sure what that looks like structurally.

    Any wisdom from the ECS vets here on achieving this separation?
     
  2. Afonso-Lage

    Afonso-Lage

    Joined:
    Jul 8, 2012
    Posts:
    70
    This is also something that I'm looking forward to see how it works. I know EntityManager has a method to do it (MoveEntitiesFrom), which should be used when you have entities ready to enter in the "view" world, so you move from one world to another.

    @MichalBUnity wrote a gist to show how worlds can be used to separate systems. You can see it here. Also read his post about this gist here.
     
    TickTakashi likes this.
  3. Goldseeker

    Goldseeker

    Joined:
    Apr 2, 2013
    Posts:
    42
    I personally think that combination of 2 & 3 is a right way to go, meaning destroying entities in many cases should be postponed and different worlds will make it easier to separate entities that should be separate. Devs have promised to roll out a sample of using 2 worlds for logic and presentation. For now everything that is related to removing and adding component and creating entities is a lot of hassle, so here is waiting for devs to fix that too.

    That being said data separation is not as important in ECS as separtion of responsibilities in OOP in many cases it is benefitial to actually keep the data on one entity in order to not manage entities linking other entities
     
  4. koplapasi

    koplapasi

    Joined:
    Jun 30, 2016
    Posts:
    11
    I think the cleanest solution would be 1) + 3). Have separate worlds for simulation/logic and rendering/view. Then pipeline those so that the rendering world operates on a copy of the simulation entity data from the end of the previous frame, while the simulation world runs the next frame. This way simulation and rendering can update in parallel, which should result in a better utilization of all the cores. Downside is the one frame lag between simulation and rendering.

    Also use events as entities to communicate changes that happened during the last simulation frame.

    Would be nice to see an example of this kind of architecture from Unity!
     
    Last edited: Jun 4, 2018
    Afonso-Lage likes this.