Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  4. Build games and experiences that can load instantly and without install. Explore the Project Tiny Preview today!
    Dismiss Notice
  5. Nominations have been announced for this years Unity Awards. Celebrate the wonderful projects made by your peers this year and get voting! Vote here!
    Dismiss Notice
  6. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  7. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Is there a tagging mechanic for ECS?

Discussion in 'Entity Component System and C# Job system' started by madks13, Dec 4, 2018.

  1. madks13

    madks13

    Joined:
    May 8, 2016
    Posts:
    159
    Hello,

    i've heard about the tags in ECS, but i couldn't find any document explaining sufficiently this mechanic. Can anyone here explain plainly what the tags are for and how to properly use them?

    Also, what i need is to put a tag/interface on an entity so it's processed by a system and then remove that tag/interface so it goes dormant until needed again (this might be anywhere between a few seconds to a few hours later).

    I'm wondering also if the tags are adapted to such a mechanism.
     
  2. jooleanlogic

    jooleanlogic

    Joined:
    Mar 1, 2018
    Posts:
    70
    I don't think there's any actual tag type (stand to be corrected if there is), it's just an IComponentData with no members (zero sized) so it is included in the makeup of the archetype but takes up no actual space in the chunk. You can thus use it as a free mechanism to group entities.

    The scenario you specified is exactly what you'd use tags for.
     
  3. BenzzzX

    BenzzzX

    Joined:
    Jun 4, 2018
    Posts:
    1
    I think there's two choices:
    1, value tag via
    ISharedComponentData

    2, type tag via zero sized
    IComponentData
     
  4. madks13

    madks13

    Joined:
    May 8, 2016
    Posts:
    159
    I'm currently using empty IComponentData as tags, but i can't add/remove them inside jobs. Which is what i'm trying to do. The reason for this is otherwise i have to add/remove those inside buffers and thise makes the whole process slower since i'm always waiting for a buffer to complete to go to next step.

    Is there a way around this?
     
  5. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    814
    Adding a tag component changes entity's chunk. The benefit you get from adding a tag comes from the fact that the data moved to group together. ECS data cannot move while inside a job, that would be a disaster. That's why you have to wait for main thread sync point for EntityManager to do its important work and make sure no one is touching the data.

    I just hope we can get chunk operation to compliment chunk iteration soon, so tagging or removing can be done fast per chunk.
     
  6. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    159
    If you have alot of freqwently changing tags it may be reasonable to use int flag instad of tag, in this case you'll pay extra iteration cost intead of data movemnt cost
     
    illinar likes this.
  7. madks13

    madks13

    Joined:
    May 8, 2016
    Posts:
    159
    Well, what i was trying to do is reduce the amount of objects processed per iteration. The reason? I have a n*m rectangle of items. The worst case scenario is that i have to change all n*m items. The best is no items will need changing. The normal case is either n or m amount of items would be changed per second (not per frame, but per second, it's a time constraint). Which is why i don't see the point of overburdening the whole syste, with processing n*m items each iteration.

    The problem with waiting for the buffers is that i find that too inefficient. I would like to process each item needing processing, then pass it to the next system as soon as it's done rather than waiting for the bulk of them to be processed. This is the kind of processing that ECS can do, but not with tags. And i don't see any other way of not processing items that don't need it other than tagging with IComponentData. If you do know a better way i'm happy to read and learn.
     
  8. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    159
    Commands in command buffer can be executed within the system update they were scheduled.
    So the next system may work with results of the previous one
     
  9. madks13

    madks13

    Joined:
    May 8, 2016
    Posts:
    159
    @SubPixelPerfect can you give me an example of what you mean? i don't think i understood what you said.
     
  10. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    686
    EntityCommandBuffer.Playback()
     
  11. Tony_Max

    Tony_Max

    Joined:
    Feb 7, 2017
    Posts:
    26
    Can you show an example of
    EntityCommandBuffer.Playback(EntityManager)
    using?

    Am I right that EntityCommandBuffer.Playback(EntityManager) function makes our CommandBuffer play on given EntityManager (system) instead of default case when CommandBuffer plays after all systems's OnUpdate()?
     
    Last edited: Dec 9, 2018
  12. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    686
    Yes, you fill buffer in loop for example, and just call playback in the end (or some where else) and this do structural changes immediatley
     
  13. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    686
    It’s depend on ECB which you use, if you use your own barrier it’s executes when you specify that.
     
  14. Tony_Max

    Tony_Max

    Joined:
    Feb 7, 2017
    Posts:
    26
    As I understand it will not solve problem with tagging. Using ECB just give you scheduling of structural changing. You can simply change structs without ECB and next systems will see this changes. Of course if I understand right what eizenhorn says.
    In case with n*m items we need tags to tell change system what items we want to change. We can use ECB inside system that decide what items must be change (let's call it Sorting system), but there will be no logic separation between systems. I mean that Sorting system will sort and then schedule changing that is actual the work of change system.
     
    Last edited: Dec 9, 2018
  15. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    159
    Adding/Removing tag component is a structural change that can't be made right inside job or during iteration.

    So to do that you have to schedule that structural changes somehow (using command buffer for example) and after job/loop completion apply those changes.

    CommandBuffer can be invoked by the end frame barrier system at the end of the frame, or by some custom barrier system, or by the system where it was created, depending on your needs.



    But in this particular case, it may be reasonable not to use tags at all
     
    Last edited: Dec 10, 2018
  16. madks13

    madks13

    Joined:
    May 8, 2016
    Posts:
    159
    The reason i want it like this is because in the current state n x m is not much, at best n ~= 160 and m ~= 80, so around 12 800 objects...except that is per layer.

    We have 2 layers (front, back), which amounts to 25 600. Add to that all the resources for each layer, which can be anywhere from 5 to 60 percent of the terrain, you get up to 40 960 in worst case. And that is per player. I want to be able to host up to 64 players. Which makes that 2 621 440 objects... if all 64 players are roaming around. ECS might be efficient but event that will cause some major spikes if all objects are processed each frame, even if there is no calculations to be done other than checking if there is a need for update.

    Then, we didn't take into account all the actors, 64 players that will need update each frame. All NPC actors (allied, neutral, and enemy ones). Add to that the fluids using physics and you have a recipe for unoptimized and laggy game.

    I know it's bad to enter the overoptimization cycle before having the basics, but i already have the basics. With one player the terrain works fine. Now i need to think about optimizations for multiplayer. And that is where i see the limit of my current implementation using tags. The spikes will be huge, i need to make it only the entities that need updating go trough the systems, and not everything. When i tried adding fluids, i encountered this problem.

    If i process all fluid parts, it's the same as processing all entities, since i can have large bodies of water taking up all the visible space. But if i do something like tagging, i would need to spread the physics in a wave like pattern, except with the current way, i would need to wait each frame to end before spreading the wave to the surrounding blocks. It's more synchronous than asynchronous.

    I've read the documentation for unity's ECS, and i'm having trouble seeing how, with the current ECS tools, i could implement something that is not an inefficient and laggy mess.

    Edit : corrected the messed up math a bit. But the conclusion is the same : too much objects to process in each frame, even for ECS.
     
    Last edited: Dec 13, 2018 at 10:40 AM