Search Unity

Spritesheet, simple explosion in ECS

Discussion in 'Entity Component System' started by Reloque, Oct 18, 2019.

  1. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    So, trying to get into ECS a bit more, and after viewing some CodeMonkey tutorials, I got to wondering, how do spritesheets fit into there?

    So, I have this simple, spritesheet; it goes boom. So, now I want to use that as an animation. Watching these tutorials;

    Getting Started with ECS in Unity 2019
    Draw a Sprite with ECS in Unity 2019
    Simple Sprite Sheet Animation in Unity ECS

    Made me think this is going to be quite complex, for such a simple thing. I can either create 23 separate materials and cycle through them. Or implement a complete seperate animation system. Both don't really feel like the 'right way'.

    I'd love to hear some insights and or comments/suggestions.
     

    Attached Files:

  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,769
  3. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    Thanks, I think the 200K topic is on the mark. Even if I don't need quite that many sprites.
     
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,769
    If it applies to 200k, I think it will work well with 1k, or 10k :p
     
  5. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    I think it will. I did misspeak a bit, I intent to have as many entities as possible, 10k, 100k a friggin million billion if I can. But, only a "handfull" will be on screen at the same time.

    Just to see what this ECS bit can do.
     
  6. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    Is this a stress test or you have a use case?
     
  7. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    Little bit of both.

    I have a use case, that need managing a whole lot of objects. But normally, I would simplify or remove those outside of the view. With ECS, I am going to see if that optimization is still needed.
     
  8. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    A minimal system, not knowing you use case, could be:
    1- camera system (sprites are animated, but static)
    2- animation system (time based)
    3- cull & render system (animation index of on-screen entities pushed into compute buffer, uv lookup in shader)
     
  9. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    I've made a thing, based on CodeMonkey's examples. But apparently, ECS has already moved beyond that. So I am looking into it again.
     
  10. Radu392

    Radu392

    Joined:
    Jan 6, 2016
    Posts:
    210
    CodeMonkey’s approach works extremely well as long as you use’re okay with having a specific frame count and other restrictions on your art. In fact it works so well that animating 20k entities with a sprite atlas of 4 by 10 frames costs apparently 0.2ms. I used CodeMonkey’s approach to calculate the stuff in a job system and it does wonders for me.

    How has ECS ‘moved beyond that’? Let me know I’m curious even though I’m not going to change my implementation.
     
  11. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    Beyond as in CodeMonkey's bit depends on a feature that will be/is deprecated;

    Code (CSharp):
    1. Assets/ECS_SpriteSheetAnim/SpriteSheetRenderer_Basic.cs(15,15): Warning CS0618: 'NativeQueue<SpriteSheetRenderer_Basic.RenderData>.Concurrent' is obsolete: 'NativeQueue<T>.Concurrent is deprecated, use NativeQueue<T>.ParallelWriter instead. (RemovedAfter 2019-10-25)' (CS0618)
    So, I'd need to rework that bit. I am trying to make something that is easily used with common spritesheets. So my spaceship can have an exhaust flame and some asteroids fly around space so to say.

    For the sheer number of objects I'd like ECS seems prime. For the complexity in managing them, well, I am learning.
     
  12. Radu392

    Radu392

    Joined:
    Jan 6, 2016
    Posts:
    210
    All you have to do is use ParallelWriter() instead of Concurrent and it will work the same :)
    CodeMonkey’s code can be further optimized. I think the bottleneck in his code was his rendering system if I’m not mistaken.
     
  13. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    Most likely. I am actually refollowing his tutorial right now, to figure out a better way for my particular use case.

    Maybe I am still looking at this too much from an OO perspective. Old habits do die hard. My case is one spacestructure for the player, many outside entities interacting with that. CM's way to set the UV's to enable use of spritesheets is usefull there. I did it a bit like this to point to a sprite in a spritesheet;

    Code (CSharp):
    1.         private Vector4 getUVForFrame(int currentFrame, SpriteSheet spriteSheet)
    2.         {
    3.             // Get the column and row for our frame in the spritesheet
    4.             // Row is rounded down
    5.             int row;
    6.             row = currentFrame / spriteSheet.xDimension;
    7.  
    8.             // And the column is the rest
    9.             int col;
    10.             col = currentFrame - (spriteSheet.yDimension * row);
    11.  
    12.             // Create the UV from that bit
    13.             float uvWidth  = 1f / (spriteSheet.frameCount / spriteSheet.xDimension);
    14.             float uvHeight = 1f / (spriteSheet.frameCount / spriteSheet.yDimension);
    15.  
    16.             float uvOffsetX = uvWidth * col;
    17.             float uvOffsetY = uvHeight * (spriteSheet.yDimension - (row + 1));
    18.  
    19.             return new Vector4(uvWidth, uvHeight, uvOffsetX, uvOffsetY);
    20.         }
     
  14. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    i recommend you look at some examples posted in #2 - for best performance you best
    - use drawmeshinstancedindirect
    - use compute buffers
    - minimize data per frame to gpu (i.e. send uvs once and then only an index, cache buffers + only send changes - this can work well with animation which does not update every frame, etc.)
     
  15. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    I want to limit the amount of custom work I'd have to do for what is, in essence, a 'simple' sprite based space shooter. To make sure the code is reusable and easy to understand. So far I've cut out all the culling bits and made it so the spritesheet can be used with a simple grid system. Ie, I can use an 5x5 spritesheet and point to a discrete frame to render it.

    I am looking into how to proceed, as of this, I can comfortably render about 2.500 simultaneously looping exploding sprites. Asynchronous, so at different points in the animation. That is about 70 fps on a MacPro without a real gaming GPU. Since I am developing for a tablet system, there should be room for improvement. The thing is, it doesn't matter if the sprites are visible in the camera or not. So really zoomed in, with only a 100 sprites in the view, it's just as slow/fast as really zoomed out. Or even with the camera moved way out of the way, not showing any sprites, still 70 fps. At 20 instances it's about 120 fps.

    Now that I've gained some basic understanding, I will probably use the https://forum.unity.com/threads/200k-dynamic-animated-sprites-at-80fps.695809/ code shared there.
     
    Last edited: Oct 28, 2019