Jump to content
  • Advertisement

Unity Part 1: Unity ECS - briefly about ecs



Some thoughts about ECS

Part 1: Unity ECS - briefly about ecs
Part 2: Unity ECS - project design
Part 3: Unity ECS - operations on Entities
Part 4: Unity ECS - ECS and Jobs


The rule of thumb explanation

How does ComponentSystem often look like:


public class SomeSystem : ComponentSystem
    private struct Group
        public readonly int Length;
        public EntityArray Entities;
        public ComponentDataArray<SomeComponent> SomeComponents;
    [Inject] private Group m_group; // Inject the group entities with given components

    protected override void OnUpdate()
        float dt = Time.deltaTime; // Nice cached deltaTime, we're on main thread, so we can use Unity's API
        for (int i = 0; i < m_group.Length; i++)
            // some operates on data
    // System was enabled (ComponentSystemBase.Enabled = true) 
    protected override void OnStartRunning() 
        // probably some more caches for optimization, preparation for Updates
    // System was disabled (ComponentSystemBase.Enabled = false) 
    protected override void OnStopRunning()
        // probably some clean up

Let's take a look at this first:

struct Group
    public readonly int Length;
    public EntityArray Entities;
    public ComponentDataArray<Foo> Foos;
    public ComponentDataArray<Bar> Bars;

What is group?

Group is filter of all Entities in active world that have Foo and Bar component
It's like array of matching entities with references to all specific given components.
So, group is like EntityArray but with references to components, EntityArray itself is just array of Entities (and entity is just an index).
Group is constructed with a set of required components, subtractive components. It's also synced.
Why do we have Length field? Isn't Foos.Length the same?
Yes, you are rigth! They're the same. Length is length of EntityArray, so also Length of Foos and Bars, because each entity has Foo and Bar component
It's more obvious in this case:
for(int i; i < m_group.Length; i++) 
    // Using m_group.Foos.Length or m_group.Bar.Length would be a bit confusing in this case
    // because we iterate over all entities and can get access to ANY of their components
To summarize - every array in injected group would have same Length, because it's length of Entities and each entity has every given component.
Separation of Length field is just for convenience.

How to manage indexing? The injection magic.

for(int i; i < m_group.Length; i++) // iterate over all entities from group
    // It's safe to iterate like that, because every array in group has the same length
    // and indexing is also injected(synced) in that way to use it exactly like this:
    var actualEntity = m_group.Entities[i];  // Actual iterating Entity
    var actualFoo    = m_group.Foos[i];      // Foo component "attached" to actualEntity
    var actualBar    = m_group.Bards[i];     // Bar component "attached" to actualEntity

How do I manage lifetime of systems?

Well, you don't really need to!
Unity takes care about that. Systems track injected groups and will be disabled if there are no matching Entities and will be enabled if there appears one as well.
But if you really want to, take a look upwards, see OnStartRunning and OnStopRunning ?
I mentioned ComponentSystemBase.Enabled = true which is probably what are you looking for. It's property that allows you to active/disable system manually.
Systems don't update in order I want
Convenience attributes for rescue! 
Since all systems are updated on the main thread, you need to think about order of updates, there are some attributes to help you with it:
[UpdateAfter(typeof(OtherSystem))], [UpdateBefore(typeof(OtherSystem))], [UpdateInGroup(typeof(UpdateGroup))]
where UpdateGroup is empty class.
You can even control update before/after Unity's phases by typeof(UnityEngine.Experimental.PlayerLoop.FixedUpdate) or other phases in same namespace.

How can I get access to system I want?

You can just inject it just like
 [Inject] private YourSystem yourSystem; 
easy as that. You can also use
or if you're not sure if it exists but it should, use


Why to use EntityArray in system? What can I do with this index?

Since systems most often operates on components, not directly on entities, it raises question "Why do I even need this index".
Saying "it's just and index" doesn't mean that is not usable at all. It's very important integer.
If you haven't tried Unity's ECS implementation, you probably don't know where is it needed.
It's needed among others for functionality from EntityManager that holds EntityData and controls adding/removing (and much more) components from a given entity.
But actually you don't want to add/remove components via EntityManager.
You'd rather do it after update to not break the group (you'll get error about accessing deallocated nativearray),
so you want to use PostUpdateCommands (EntityCommandBuffer). More about that in one of futures part of article.

World vs EntityManager

EntityManager is not weird, magic class, it's ScriptBehaviourManager and "merges" entities and their components.
In ECS we have a lot of managers. ComponentSystem is also ScriptBehaviourManager !
World  holds all managers in one piece. We could colloquially say it manages the managers.
I know what's your question - yes, we can create multiple worlds, sounds interesting, isn't it? Maybe we'll take a look at this in future.

ComponentData and SharedComponentData. What's the difference?

The difference is trivial, ComponentData is just a component, SharedComponentData is as it says, component shared between different Entities.
Very good explanation you can read in docs:

IComponentData is appropriate for data that varies between Entities, such as storing a world position. ISharedComponentData is useful when many Entities have something in common, for example in the boid demo we instantiate many Entities from the same Prefab and thus the MeshInstanceRenderer between many boid Entities is exactly the same.

So, with same IComponentData (eg. Position) changes from Entity0 won't change Position from Entity1,
ut with same SharedComponent (eg. Renderer) if you change material from Entity0, it'll change also material from Entity1.
However you don't really want to change SharedComponents a lot, actually very rarely. More details THERE.
Well, there is one more difference - ComponentData have to be blittable.

Oryginally published at: https://connect.unity.com/p/part-1-unity-ecs-briefly-about-ecs

Go further:
Part 2: Unity ECS - project design

Give me some feedback in comment section, don't worry I won't hate you if you show me some "anomaly" in my article.
If you enjoy my article - like it and follow me. It'll motivate me to write more articles. See you.

1 Comment

Recommended Comments

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By horror_man
      Hello, I'm currently searching for a talented and passionate programmer to create a small but great horror game that would take around 3 months to be done.
      About the game: The game would be a sci-fi/post-apocalyptic survival horror 3D game with FPS (First person shooter) mechanics and an original setting and story based in a book (which I'm writing) scene, where a group of prisoners are left behind in an abandoned underground facility. It would play similar to Dead Space combined with Penumbra and SCP: Secret Laboratory, with the option of playing solo or multiplayer.
      Engine that'd be used to create the game: Unity
      About me: I'm a music composer with 4 years of experience and I'm fairly new in this game development world, and I'm currently leading the team that'd be creating this beautiful and horrifying game. I decided that making the book which I'm writing into a game would be really cool, and I got more motivated about doing so some time ago when I got a bunch of expensive Unity assets for a very low price. However, I researched about how to do things right in game development so I reduced the scope of it as much as I could so that's why this game is really based in a scene of the book and not the entire thing (and also that's why it would take 3 months). Also I'm currently learning how to use Unity and how to model things with Blender.
      Our team right now consists of: Me (Game Designer, Creator, Music Composer, Writer), 3 3D Modelers, 1 Sound Effect Designer, 1 Concept Artist and 1 Programmer.
      Who am I looking for:
      - A programmer that's experienced in C# and with Unity.
      Right now the game is very early in its development (GDD is completed and all 3D Items, Music and Sound Effects are completed).
      If you are interested in joining, contributing or have questions about the project then let's talk. You can message me in Discord: world_creator#9524
    • By kcirkl
      So, I'm aware this may be a broad question with a vast variety in the anwser. However, I am a game design student that works professionally for a large engineering company conducting software configuration. Naturally, I'm curious about the path ahead and I'm desperately gathering information on the overall process of developement with Unity. Are there professional resources available that can outline the processes and functions of the engine, and what can be used to interact with it? I'm looking for options other than the official documentation. I have already jumped into that. Thanks!
    • By tspartant
      Hey everyone! My name is Ryan and I am the founder of Visualistic Studios, LLC. 
      I'm looking for experienced developers interested in short term and long term contracting. For the past 3 years I've been working in game development contracting, and the past year I've been working full time from home. Since then, I've received more and more contracts and I'm now at the point that I have too many for myself to handle. I have at least another full time job's worth of programming offers, and around 30-80 hours a month for 3D modeling/animation. I also am in need of a UI artist, so if you're talented please contact me! I have contracts using Unity as well as Unreal Engine 4, so if you can program in either please contact me. 
      If you are interested in working on these contracts, please send me links to your work and you hourly rate. (Most contracts range be between 18-25$/h, but please provide your normal hourly rate)
      You can get ahold of me through email - "ryan.hobbs@visualisticstudios.com", or Discord "TSpartanT#4670"
      Thank you everyone for reading, hope to hear from you soon!
    • By bertan otun
      I need help, I just started learning today (about programming). But I dont understand what I am doing wrong I am getting a error message: Assets/PlayerMovement.cs(10,9): error CS0117: UnityEngine.Debug' does not contain a definition forlog' I found the problem (its about the captials.)

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!