Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Need a bit of explaining by example...

Discussion in 'Entity Component System' started by itsDrew, Aug 30, 2018.

  1. itsDrew

    itsDrew

    Joined:
    Aug 16, 2017
    Posts:
    32
    I'm trying to understand the 'why' of using ECS over the classic system. I've watched some videos and read some docs, but I'd like to know specifically why / if ECS is more efficient.

    10 cubes on screen.
    Each cube has a random rpm.
    Each cube has a random velocity that changes every second.
    Cubes rotate and move for 5 seconds.

    I could be totally wrong about this, so bear with me....

    In a classical sense we spawn each cube with a transform, renderer, rotator, and velocity-changer component. Every one acts independently.

    In a an ECS sense, there is a transform, renderer, rotator, and velocity changer 'controller'. Each controller has an array (or something) with references to the entities that it acts upon. Controllers act independently.
    Doing it this way, the way data is stored and accessed is more efficient than the classical system.

    If thats true (and thats a big if, since I really have no idea if that's correct), couldn't we do pretty much the same thing in classical unity by just putting 'controller' objects in the scene with arrays referencing each spawned object's transform?

    Be gentle :p and feel free to provide any links to outside references you think will help (bearing in mind I've already tried reading/watching a few of the more 'popular' google searched ones).
     
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Entity is an id
    Component is data
    System is the "controller" you speak of. It's actually a system though and should be called as such.

    The whole point of splitting things up like this is so that CPU can can linearly access packed data, and make use of the caches properly and make use of the CPU's prediction pipelines.

    What you suggest would be the same performance as existing Unity, ie you access something on another object, it loads the entire class's variables into the CPU cache, which is basically putting traffic lights every 10 meters along a road.

    It's likely I didn't understand what you mean though...
     
  3. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    Each object's transform is located at a completely different location in memory and needs to get fetched into CPU registers.
    ECS: go into street X, paint house red, goto neighbouring house, paint house red, goto neighbouring house, paint house red
    Classic: goto house X on earth, paint house red, goto house X on moon, paint house red, goto house X on Mars, paint house red
     
  4. itsDrew

    itsDrew

    Joined:
    Aug 16, 2017
    Posts:
    32
    Sorry about the terminology... I'll try to be more accurate.

    Picking one system out... what I was saying is that a classical scene would contain something like a 'RotatorSystem': An empty game object with a RotatorSystem component.

    The rotator system class would have a rotatorSystem.objects array.
    As empty game objects (that we want to be a cube) are spawned, they would be added to that array.
    Every frame, the rotatorSystem would iterate through the array and run 'rotatorSystem.rotate(itemInArray)' which would directly alter the transform of the itemInArray.

    Is that similar to the way ECS works on a higher level?

    Though I guess I can see now how it wouldn't work with the current system since transforms have to be modified individually and there can't be a 'transformArray' that neatly packs since it has to reference individual transform components.

    I think I need a bit more understanding of how memory allocation and memory access works with the current system.
     
  5. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    Yeah, that would basically be the ECS pattern but you are iterating a list of transform references pointing to totally unrelated places in memory where Unity's ECS iterates over the data directly. Each time data is accessed the data has to be available to the CPU. If it's not in the cache it will be fetched from main memory, which is really slow. In your 'solution' this will happen for each Transform in the list. In Unity's ECS it will basically never happen as the transforms are actually stored one after another and the CPU will prefetch the data while processing the data currently in cache.
     
  6. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    Check out the second half of this video: https://channel9.msdn.com/Events/Build/2014/2-661
    It's an old video, but it explains really well how data locality works and why it's sooo fast.

    Also, this article explains data locality really well too and it's a fun read: http://gameprogrammingpatterns.com/data-locality.html

    Once you have wrapped your mind around how data locality works (and the terminology behind it), it's important to note that in order leverage the power of the L1/L2 cache, you have to use structs! It won't work with objects, since objects are reference pointers and that will always result in a cache miss. That's one of the main reasons data locality can't be done on with unity's classic system (it's inherently object oriented).
     
  7. Ahlundra

    Ahlundra

    Joined:
    Apr 13, 2017
    Posts:
    47
    you have a sword
    you want that sword to do fire damage
    you make every class needed, their inheritance, everything and it is working beautifully with no problems

    then someone working with you wants to make the sword do ice damage

    he will need to read every script you made and even worse, he will need to make CHANGES to it to allow for this new element to work. You cant do anything in that script while he's working on it and his changes may break something in another system that you'll never be aware of, well, that is... Until you make something new and receive the message the system broke for some unknown reason =p

    it could take weeks to find the problem or even to know about it's existence.

    if this was ecs, that someone could simply make a component called ice damage and make the "ice damage" system just add the ice damage to the "damage" component before the "do damage" system is called.

    even if it was just you by yourself adding new elements to your game it would be a lot easier.
    for me that is reason enough to use ECS even if it didnt have the benefits of jobs and burst
     
  8. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    969
    Wow! An array list is still faster than a linked list up to 500k elements.