Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

what is the best way to create entity to gameobject mapping

Discussion in 'Entity Component System' started by Ashkan_gc, Aug 27, 2019.

  1. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,103
    Hey all
    We are doing a deterministic sim with ECS and intend to do the whole view layer in GameObjects.
    Currently the way that i'm doing it is like this (since Gameobject Entity is deprecated)

    1- we have authoring components and lightweight IComponentData components and we use conversion to convert from a classic prefab to a ECS prefab.
    1.1- each classic prefab has two versions, one (called P1) with the ConverterToEntity component and another with a custom componenet called EntityMapper which is a MonoBehaviour with a public Entity field (we call this p2).
    2- when instantiating we convert the classic prefab p1 once to a entity representation and then instantiate this representation and p2 together at instantiation times. we set the p2->EntityMapper.Entitty to the newly instantiated entity.
    3- our Monobehaviours read the state of the ECS components in their late update and update their view and also if the entity no longer exist, they destroy themselves.

    At first we tried to just instantiate a classic prefab with ConvertToEntity component which automatically creates an entity but it was slow like hell and I looked at the converter's source code and understood why.

    Is what we are doing the best approach?

    After i'm done with our basic framework, i'll document it all in a gamasutra article and will post it here too.
     
  2. mukultictoc

    mukultictoc

    Joined:
    Sep 24, 2016
    Posts:
    15
    I ran into a similar issue.
    What I did was use the ConvertToEntity and store that entity in like PoolableEntityDatabase.
    Whenever i wanted an instance of that entity, I would ask the PoolableEntityDatabase to Instantiate a new entity from the original blueprint entity that was created at start from "ConvertToEntity" and create the game object as well. Then call GameObjectEntity.AddToEntity to map the game object to that new entity and return it. This removes the process of using converting game object in runtime to an entity, which is super super slow.
    It works for my purpose. I am not sure if that is the best method though.
     
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,993
    Have a look at Unity.Rendering.Hybrid and notice how they do lights. Lights for Unity's backend are still GameObjects, and they have a pool of them, and every frame they update those GameObjects from the data stored on entities.
     
    psuong likes this.
  4. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    As far as instantiation flow I think that depends hugely on the game. How your data flows. If you are loading a scene with a lot of scene scoped gameobjects and components with data, entity conversion makes sense. If it's like our game where it's all network driven there is no conversion per say outside of specific built in components like transforms.

    For synchronization of hybrid data we have a very specific design. It starts with strong separation of data and logic. So we don't synchronize data between ECS and monobehaviors per say. ECS is generally authoritative and then we have read only copies of some logical entities for consumption outside of ECS. We maintain those copies by updating them every frame inside a job.

    Input is about the only thing where authority is not in ECS (which stems mostly from network messages fed to ECS).

    And since we don't really have entity conversion we just use the lower level batch api's directly.

    Our instantiation flow is create the gameobject first. That is sort of forced by needing to feed the transform to the entity creation. Then queue whatever data is needed by ECS for a system that picks it up and batch creates entities. We use a single system for this, it's our only sync point.

    Destruction we destroy entities then gameobjects. Transforms again kind of force this flow.
     
  5. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,103
    @snacktime @DreamingImLatios @mukultictoc Thanks for sharing your experience guys.
    I'll look at the hybrid renderer.

    Chris i'm interested to know just out of curiosity what kind of game are you working on.

    Ours is networked too and i'm trying to build an easy to use game specific simulation framework for our team. the game is not perf heavy so I have a relatively easy job on that front. We are however trying to achieve good enough determinism so replays can be done only using input/commands and that's the challenging part.
     
  6. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,103
    @DreamingImLatios could not find the code in question. can you let me know where is it? thanks
     
  7. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,648
    com.unity.rendering.hybrid@0.1.1-preview\Unity.Rendering.Hybrid\LightSystem.cs
     
  8. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,103
    @tertle thanks. I was looking at an older version which had no light systems
     
  9. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    It's I think most similar to https://store.steampowered.com/app/834910/ATLAS/. Main difference is in our game every player has their own ship.