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

Showcase Kitchen Chaos ECS

Discussion in 'Entity Component System' started by imaginadio, May 25, 2023.

  1. imaginadio

    imaginadio

    Joined:
    Apr 5, 2020
    Posts:
    60
    Hello everyone! I want to learn more about unity and found this amazing free complete course from @CodeMonkeyYT https://unitycodemonkey.com/kitchenchaoscourse.php
    Codemonkey, if you reading this - big thanx! You are awesome!)

    But I really like ECS pattern and decided to complete this course using ECS. Of course this is not 100% pure DOTS solution, but all the logic and most of rendering are made using ECS. I left UI, sounds and animations for MonoBehaviours. Btw thanx for such hybrid approach idea to @WAYNGames, your videos helps me a lot also.

    Here is my repo with complete game https://github.com/AndroiDjo/KitchenChaosEcs
    I missed gamepad chapter only, because I dont have one for testing.

    Im new to C#, unity, ECS, so if you can give me some advises - I would really appreciate it.
     
    Occuros and CodeMonkeyYT like this.
  2. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Well done

    I've looked briefly through the system logic, as for the advices:
    1. More systems can be ISystem. Free performance.
    Basically anything that does not require main thread access or complicate access (e.g. in case of lookup system);
    2. You can get rid of random system and store random inside the component data.
    Less dependencies to manage, less code to write at a minor cost of uint. Usually worth it.
    3. Fetch systems in OnCreate instead of Update. Cache refs inside the system to use in OnUpdate.
    4. Afaik, adding dependencies to the ECBSystem manually no longer required since 1.0.
    (it should be autogenerated, but I haven't tested myself)
     
    imaginadio likes this.
  3. CodeMonkeyYT

    CodeMonkeyYT

    Joined:
    Dec 22, 2014
    Posts:
    124
    That's really awesome! I was thinking of doing exactly that when ECS 1.0 came out, really great job!
    What was the toughest part in doing this conversion? Mixing the UI with ECS Systems?
    I haven't yet looked into the final ECS 1.0 so can't really give any specific feedback but looking at the GitHub everything looks really well organized so again congrats on such an interesting conversion!
     
    OldMage, imaginadio and Occuros like this.
  4. imaginadio

    imaginadio

    Joined:
    Apr 5, 2020
    Posts:
    60
    No, mixing UI with ECS is pretty simple with the help of managed components or singletons. You just need to save, for example, Animator class in managed component and then play the animation when you need.
    The toughest part was when I tried to save the last interacted entity, like every counter memorized who interacted with them, what ingredient is on it, in what status is it ingredient, and I drowned in need of changing these statuses manually on every action.
    Then I just make one point of truth - Parent component of ingredient. When I need to take something into player's hands or put something on the counter, I just change the Parent component of ingredient. Then other entities check their children and get info of what are they holding.
     
    Last edited: May 28, 2023
  5. imaginadio

    imaginadio

    Joined:
    Apr 5, 2020
    Posts:
    60
    Thanx for feedback!
    About ISystem, why it is free perfomance? Isn't SystemBase Entities.Foreach working with burst? Why ISystem better than SystemBase?
    I just really doesn't like to write a lot of code to make a simple job in ISystem in comparison with Entities.Foreach, and I want to know the reason why is it worth it to move to ISystem instead of SystemBase)
     
    Last edited: May 28, 2023
  6. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    ISystem is restricted to structs. Meaning ISystems do not allocate heap memory (faster creation) on their own and overall iteration speed is faster even without Burst. You can also BurstCompile the actual OnUpdate method. By default while what inside ForEach is BurstCompiled, actual scheduling on the main thread [OnUpdate] is not.

    By using ISystem + BurstCompile you get faster scheduling - less time wasted on main thread.
    Which is usually a major timeloss while having 100+ systems. Its a low hanging fruit. So its worth writing ISystems by default. Falling back to SystemBase only if something managed is required (or for convenience sake e.g. for lookup systems).

    EFE also works with ISystems, so there's minimal difference as of right now in terms of LOCs.
    With empty implementation of methods such as OnDestroy in ISystem interface - its probably even less LOCs compared to SystemBase.
     
    Last edited: May 28, 2023
    tmonestudio likes this.
  7. imaginadio

    imaginadio

    Joined:
    Apr 5, 2020
    Posts:
    60
    Thank you for the explanation. I think I should consider moving to ISystem.
    Btw Entities.ForEach does not supported by ISystem:
    upload_2023-5-28_12-36-28.png
     
  8. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Right, it was removed in 1.0. Forgot about it.
    Use IJobEntity instead. Should be robust and actually working now.

    Pros:
    - Scales better with number of components over time. Easier to maintain;
    - Jobs can be reused in multiple systems;

    Cons:
    - Typing (can be mitigated by IDE auto-gen template)
     
    Last edited: May 28, 2023
  9. imaginadio

    imaginadio

    Joined:
    Apr 5, 2020
    Posts:
    60
    I have one more question: is there any sense to schedule a job that only enable some enableable component using EntityCommandBuffer? Or it will be fine to just enable component using SystemAPI.SetComponentEnabled() in main thread?
     
  10. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Usually its worth it. Because you're not stalling other dependent job chains.
    If you've got entities already fetched, you can just add command to the ECB without anything extra.

    Ideally something like .SetComponentEnabledForEntityQuery would be great to have so that whole query gets enabled / disabled. Similar to structural changes / tags for the cases where you don't want to modify single entity, but rather all of them without scheduling. But I guess its not there yet.
     
    imaginadio likes this.