Search Unity

EntityManager.GetComponentData performance

Discussion in 'Entity Component System' started by CaranElmoth, Sep 18, 2019.

  1. CaranElmoth

    CaranElmoth

    Joined:
    Dec 6, 2012
    Posts:
    3
    Hello everyone,
    I'm a veteran Unity programmer and I'm moving my first steps with DOTS. I'm really enthusiastic so far.
    I'm building a very small project, trying to devise some patterns and best practices.
    I'm sorry if this has already been answered, but I searched for a while and can't seem to find an adequate answer.
    What I'm trying to figure out now, is the best way to synchronize GameObject components that are not yet translated into full dots, like sprites and tiles, for example, with entities that represent their status. My central question is:

    How is EntityManager.GetComponentData performance wise? Is it feasible to use it in a GameObject's Update to poll the underlying ecs status and update the GameObject accordingly?

    Some context:
    I have a System that, based on a component data authored via gameobject conversion in the inspector, generates a maze with backtracking.
    It then generates and caches a NativeArray of entities that represent tiles to visualize the maze.
    Next I have a script attached to a TileMap in the inspector that fetches the generator system with the NativeArray of entities and uses it to setup the actual tiles to visualize.
    So far so good.
    Now, the tiles alpha channel has to change according to some tile component data that's managed by other ecs systems. What I'd like to do is, in the TileMap Update method, to use EntityManager.GetComponentData to fetch all the tiles statuses, check for changes and update the actual tiles in the TileMap.
    If there's a better way to achieve this, I'll be happy to know, of course.

    Thank you all for any help.
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,264
    The best thing to do is write a test and profile it and find out if it is good enough for your game's needs.

    However, unless you are using some fancy feature of tilemaps, it would be more performant to convert the entire tilemap into an ECS representation. It is one of the easier built-in systems to convert as a tile is just a quad rendermesh and then you have some entity with a dynamic buffer to hold the tilemap and a system to sync it all.

    But if you are just trying to get your feet wet, do something in 3D. Keep it simple. Spawn a bunch of stars in outer space, and then spawn a bunch of space ships that move around. You will learn a lot more about patterns and best practices with something like that which is better supported by DOTS out of the box (2D support in DOTS is a little behind at the moment).
     
    cirocontinisio likes this.
  3. CaranElmoth

    CaranElmoth

    Joined:
    Dec 6, 2012
    Posts:
    3
    That's what I'm planning to do, actually.

    Yes, I know that, but as I said, tiles and sprites are just an example. Since a lot of systems are yet to be translated into full DOTS, and they won't be in the near future, I figured that learning patterns to synchronize status between entities and GameObjects (both ways) can be a good idea.

    Been there, done that ;) Good advice, anyway.

    Thanks for your answer!
     
    cirocontinisio likes this.
  4. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,264
    Sounds like you got a good handle of things. If you are sticking to hybrid synchronization, EntityManager.GetComponentData certainly isn't slow. Probably comparable to gameObject.GetComponent though I haven't tested it. If you got a strong mapping between entities and their GameObjects, you might get a speedup baking the ComponentData to a NativeArray as an intermediate step which makes the chunk and entity lookup part Burstable.
     
    cirocontinisio likes this.
  5. UsmanMemon

    UsmanMemon

    Joined:
    Jan 24, 2020
    Posts:
    87
    I know it's late but for future viewers
    How about making a system which has a public function UpdateTileStatus which does something like Entities.foreach on tiles and schedule it and the function return native array of status of tiles This way you call the function from mono using World.worldName.EntityManager.GetExistingSystem<systemName>().UpdateTileStatus to get Native array.. Note only if Getcomponent is slow I haven't tested Getcomponent performance but scheduling it on multithread should make it faster too.you can also make some jobs for it too like IJob chunk and IJob parallel.