Search Unity

Official Samples

Discussion in 'Entity Component System' started by MartinGram, Mar 20, 2018.

  1. MartinGram

    MartinGram

    Administrator

    Joined:
    Feb 24, 2017
    Posts:
    72
    Djo_krd, twobob, emadkh and 10 others like this.
  2. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,363
    The samples all seem geared towards high performance using DrawInstanced internally, I guess. So when an object is displayed in the scene, it doesn't exist in the hierarchy view which makes inspecting and reverse engineering to learn how things are done very hard.
    So it would be great to include an ECS example or two that still uses GO, transform, prefabs like the old way, just the game logic is ECS, this way we can transition one bit at a time.
     
  3. gl33mer

    gl33mer

    Joined:
    May 24, 2010
    Posts:
    281
    Is the Nordeus demo available for download?
     
  4. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    @laurentlavigne --- i have not looked at it myself but the TwoStickShooter example sounds like what you are looking for (it has a classical / hybrid / pure folder)

    @gl33mer - I have not downloaded this, but this could well be it or some version of it TechDemo
     
  5. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    223
  6. gl33mer

    gl33mer

    Joined:
    May 24, 2010
    Posts:
    281
  7. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    RootCauseProductions likes this.
  8. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    The TwoStickShooter Hybrid scenes are made to do exactly that.

    Also check out Windows -> EntityDebugger. It is our first step into visualizing pure entities. We still have a lot of work ahead of us but its already a good tool to inspect all your systems & entities in the world.
     
    Last edited: Mar 20, 2018
    james_unity988, twobob, Djayp and 4 others like this.
  9. Micz84

    Micz84

    Joined:
    Jul 21, 2012
    Posts:
    451
    Where can I download 2018.1b12?
     
  10. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
  11. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,363
    Thanks guys, I found the twinstickshooter.
    Questions:
    1. The Hybrid is very convoluted. Is it because all the wrappers would be moved to engine?
    2. I think Classic seems purposfully badly programmed. Nobody calls findobjectoftype for each object per frame, instead use self registration to a global.
    3. Pure has Wrapper plumbing with comment about c++, does this mean it will disappear and move to the engine? They seem very generic already.
    4. What is this thing about injection vs foreach etc...? Can someone explain the difference?
    It seems to show only what entity use a system and how many ms that eats up. I like ECS but it's very opaque. I'd say first thing to implement is a way to inspect entities like a classic object. In fact a good way to ease the transition and replace monos with ECS is to show the entities and systems in the hierarchy panel and allow selection and inspection in the same old way.
    Looking over the ECS code, I have to say I really really like what the code looks like, so pure and non object-y :)
     
    Shizola likes this.
  12. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    Yes, I wish they had some examples that try not to show off the system but rather take you through the basics step by step. I guess this will come in time.

    I followed @Spy-Shifty 's implementation of his "pre-make" of how he assumed Unities ECS would look like and I found it more friendly to get going...(it's not really maintained, did not do jobs, etc.) so has it's own flaws but still, if you are new to ECS it's possibly a good alternative read to get going
     
  13. xenonsin

    xenonsin

    Joined:
    Dec 12, 2013
    Posts:
    20
    I've ran both the Hybrid and the Pure examples.. and in the profiler it seems the Pure example spikes up to 30fps pretty frequently while all other examples run at around 250fs. Is there something going on that is affecting performance in the pure example?
     
  14. auhfel

    auhfel

    Joined:
    Jul 5, 2015
    Posts:
    92
    I posted a thread about accessing values from ComponentDataArrays in ComponentSystems being super slow. I'm fairly sure that this affects the InstancedRendering system the Pure sample uses, and would explain slowness. It appears that there are debugging checks that slow it down. I might take a second look at the Pure scene and see if it's the same thing, I'm fairly sure it probably is.
     
  15. auhfel

    auhfel

    Joined:
    Jul 5, 2015
    Posts:
    92
    I tried out the hybrid and original samples, and in my case the pure performs better than the rest. Not by a whole lot, but by a bit. I certainly wasn't getting 250fps on any of the projects lol. I dunno though, but that's what I got when I tested them.
     
  16. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Please note:

    1) In the editor by default the Job debugger & full race condition checks are on by default
    2) Leak detection is enabled by default
    3) Burst by default compiles with safety checks

    All of this has noticable overhead. In the jobs menu you can turn all of them off in the editor. (Disabling all safety resulting in that Unity might crash when you accidentally introduce race conditions) So this is good to have on as a default, but when profiling you should turn them off.
     
    LazyMonkey, Krajca and laurentlavigne like this.
  17. asethi

    asethi

    Joined:
    Jul 24, 2012
    Posts:
    16
    I have downloaded the samples and opening them in Unity 2018.1b12, but keep getting many Burst Compiler related errors like below.
    C:/ProgramData/Unity/cache/packages/staging-packages.unity.com/com.unity.burst@0.2.1/Editor/BurstReflection.cs(19,67): error CS0246: The type or namespace name `AssembliesType' could not be found. Are you missing an assembly reference?

    Am I missing anything?
     
  18. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    223
    asethi likes this.
  19. asethi

    asethi

    Joined:
    Jul 24, 2012
    Posts:
    16
  20. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
  21. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,363
    you need to download a bunch more stuff, read the readme.md on his github
     
  22. RDeluxe

    RDeluxe

    Joined:
    Sep 29, 2013
    Posts:
    117
    To be frank, I have a hard time wrapping my head around the new ECS system. How to use it in cases when you want each entity to have methods such as `Attack`, `Die`, etc, not wrapped up in the `Update()` logic but triggered by UI input for example.
    Right now we are working on a turn based, tactical game, and it seems like the ECS system is really targeted at games having a heavy use of the Update loop, which is not our case (except for the UI and our FSM).

    Also wondering how Polymorphism is going to be managed by all this. It's really practical to be able to do a reversed for loop on my `List<Creatures>` and use the virtual method `creature.Die()`, to trigger a specific animation, sound, FXs, etc.
     
    Krajca likes this.
  23. tbg10101_

    tbg10101_

    Joined:
    Mar 13, 2011
    Posts:
    192
    Instead of using inheritance, you use components. So all of your creatures have a Creature component and all your dragons have a Dragon component. Then you make a Dragon system (or perhaps multiple systems) that takes Creatures and Dragons that does some processing on them.

    ECS isn't for every game so try some experiments and see if it works for you.
     
  24. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    I am trapped in an airport for 12 hours, so I will go ahead and try to explain as best as I can:
    • Q: "How to use it in cases when you want each entity to have methods such as `Attack`, `Die`, etc, not wrapped up in the `Update()` logic but triggered by UI input for example."
      • A: So in the case of UI or anything else that's not ECS-ified, You can create a bridge, either by having a GameObjectEntity on it (like most of the hybrid samples) and manipulating it's ECS Components (you can add/remove both pure ECS components, as well as ones that are wrapped with the MonoBehavior wrappers), or you can simply call the entity API functions on the EntityManager to create and send "event" entities that tell the ECS something happened, along with some context data.
    • Q: "Right now we are working on a turn based, tactical game, and it seems like the ECS system is really targeted at games having a heavy use of the Update loop, which is not our case (except for the UI and our FSM)."
      • A: You don't necessarily have to tie it to the normal update loop, there are special "Barrier" systems that act as sync points for various parts of the update loop (still need to dig into the specifics of this myself as a lot of what I want to do would be split between Update & FixedUpdate).
      • You also don't have to force all of your code to be ECS-ified at first. It's fine to have GameEntityObjects with components that just tag certain objects for non-jobified systems.
      • It's also fine to use the Job stuff without using the ECS at all (although the frameworks complement each other extremely well from what little I've been able to dig into and watching the talks at GDC).
    • Q: "Also wondering how Polymorphism is going to be managed by all this. It's really practical to be able to do a reversed for loop on my `List<Creatures>` and use the virtual method `creature.Die()`, to trigger a specific animation, sound, FXs, etc."
    • A: The kind of weird, beautiful thing is an ECS offers a sort of "perfect" polymorphism, each component determines what an entity is (as an entity is just a way to index a set of grouped components), and therefore the logic that operates on it. You get the full benefits of Composition AND Polymorphism this way.
      • As an example in an RTS:
        • An entity could be a Unit with Health and a Sprite, and this would be represented with a Unit component, a Health Component, and a Sprite Component. A building would have a Building component as a tag and a person would have a Character (tag). If the character or building has animations, they could have an Animation component.
          • The Unit's data determines team (and possibly owning player id).
          • The Health component is a simple int, maybe with Max range.
          • The Sprite component has data indicating the sprite id.
          • The Building and Character components function as tags, and are empty (no data).
          • The Animation component has the current animation id (relative to the sprite, let's say), and play time (let's assume a simple 2d sprite animation, no mechanic).
      • Most of the systems for taking and healing damage don't know or care anything about the animation system. If we get to the end of a frame with our health at zero or less, we remove the health component.
      • The actual Unit kill system only looks for a Unit WITHOUT Health, and spawns a death proxy that only has a Sprite and Animation components, and the animation is set to the "death" animation settings. The death proxy itself could have SpawnVariousExplosions and SpawnDeathAudio components, and so on and so forth, depending on the tags it has.
      • You could have a special Unit that is both a Person and a Building, if you had the systems setup and some specific bookkeeping Components (like a Mech that turns into a base, or a druid that turns into a tree), and getting the logic setup wouldn't require doing some awkward subclassing or hot-gluing MonoBehaviours together that might have been tightly coupled to specific other MonoBehaviours.
    We're all still figuring this thing out, and how it can relate to our projects. I agree with another dev who was at GDC: Almost no project in full production should be hard pivoting to full ECS this year (Hybrid can be used as applicable). We'll need at least 6 months~1year to retrain most engineers and to see how to rethink in this new format (while waiting for API bits and bobs to catch up).
     
  25. RDeluxe

    RDeluxe

    Joined:
    Sep 29, 2013
    Posts:
    117
    Thank you both.

    There no reason not to use inheritance AND a component system. Let's say you have monsters in your game, with all the same behaviors (Die, Attack, Run) but slightly different implementation. You would want only 1 system to handle all of them, and that's when polymorphism comes handy. OOP sometimes has its use !

    It's way prettier, in my experience, to have a nice (not too big, not convoluted) OOP structure and virtual methods instead of having to manage,in your system, a huge switch/case or if/else list like
    if(c.Type == Character) { //dostuff } else if (c.Type == Monster) { //dostuff slightly differently }
    . This is definitely something I would hate to see.

    A classic example could be a Serialization() and Deserialization() feature that you want all your Monsters to have, despite their type, but each sub-class can customize those methods to correctly serialize its specific info. You can simply serialize all your monsters at once thanks to polymorphism.

    With ECS, seems to me like this will be the responsability of the system, and it can quickly get over-complicated and bloated. In it's current form, I find it quite complex. Mind you, one of my first goal when I'm writing and setting my architecture is re-readablity. While taking a look at the samples

    Maybe I'm wrong, and maybe ECS is not meant to replace the current implementation at all, but as another tool up our sleeves. I guess that's really the question: is ECS meant to be the ONLY way to code within Unity ? That's actually what I thought when I first learned about it.

    In it's current form however, I don't see an efficient way to set it up in my project without sacrificing a lot of readability. And maybe it's totally normal.
     
    leni8ec, Alverik and Gru like this.
  26. FastTurtle222

    FastTurtle222

    Joined:
    Dec 24, 2017
    Posts:
    28
    "Entity–component–system (ECS) is an architectural pattern that is mostly used in game development. An ECS follows the Composition over inheritance principle"
     
  27. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    about performance: 10 pic fish still low fps,and confused with which code is start the game? is "JobComponentSystem"? No Monobehavior how to start the logic?? fish.jpg
     

    Attached Files:

    Last edited: Mar 25, 2018
    tigerleapgorge likes this.
  28. forestrf

    forestrf

    Joined:
    Aug 28, 2010
    Posts:
    231
    Check if you have vsync enabled and disable it
     
  29. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    The profiler is telling you that it's waiting for previous frames graphics to complete and it has to wait 10ms to complete that.

    Its likely that your GPU is not very fast (Intel integrated maybe?) The demo using postprocessing image effects, terrain and PBR.

    With large numbers of boids, low-end GPU's, the demo tends to be GPU bound. The fish model is around 500 triangles and we haven't added any LOD for it. You could try swapping the mesh to be a builtin cube instead, this could prove to you that it is in fact GPU bound.

    Also not sure why antialiasing & forced anisotropic texturing is on in our demos. Try turning those off.

    In any case there is some homework for us as well, which is tweaking the demos on low-end GPU's making sure everything is configured right to run as fast as possible there. We haven't really tested for that yet. It being preview and all...
     
    twobob and laurentlavigne like this.
  30. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    Had remove camera effect,and only 10 fish,not big mesh render,cpu is still so high,and change fish to box render,still so high.
    fish.jpg fish3.jpg
     
    Last edited: Mar 25, 2018
    tigerleapgorge likes this.
  31. You're thinking about this wrong, I believe.
    You do not implement the whole object-behaviors at once. Just break it down to simple things, what's in common in the Character and in the Monster?
    Both have the same type of health? Build a health EntityComponent.
    Both have animations? Build an animation EntityComponent.

    It's like inheritance but forget the objects, do not encapsulate all of these data and behavior and then try to work out the differences. You build EntitySystems and Jobs and then apply them to certain objects (Composition). It is a little like the components in the regular OOP Unity (minus the inheritance and actual objects).
    If you're doing right, very little code will be duplicated (probably almost zero), since it will be driven by the data you have and the data-transformation you have to do.
     
  32. Gru

    Gru

    Joined:
    Dec 23, 2012
    Posts:
    142
    I just read Joachim's answer in another post "Like I said we are not planning to phase out monobehaviour or game object." This clarifies things for me a fair amount.

    My thoughts after some minimal testings with ECS:

    Preferring composition over inheritance does not mean ditching inheritance. Design patterns use this principle and still use inheritance. There are plenty of places where inheritance is useful. ECS violates all the basic principles of OOP: No polymorphism, No encapsulation, No inheritance - it is in fact anti-OOP by design.

    @RDeluxe is right, the new system is weird at first. I haven't had enough time to fully explore the mindset and all the consequences the new limitations bring. I recognize the value of and have played with jobs, and recognize the value of this system where there are large amounts of entities. The problem I have is the "one way to write code" idea. Locking into any one way to write code a certain way is a bad idea. I would be super happy if we got the ScriptBehaviour (MonoBehaviour2) to live alongside this system, which would be a MonoBehaviour reemagined. It would be a reference type and wouldn't be usable with jobs, but that's fine. Back to procedural thinking?

    The code quality of the "Classic" Two Stick Shooter is pretty bad. Nobody writes production game code this way. I hope.

    This is how we do it today (if we want to do it properly), we add reusable components. The problem is we can't have PlayerHealth and EnemyHealth that derive from HealthComponent. Instead of code reuse, we have code duplication. It seems all the systems that use any of these components have to be duplicated (I bet interfaces are not allowed, haven't tried though).

    I have a large shared codebase that uses properties of MonoBehaviours as they are today. Potential deprecating of MBs for Unity community will mean rewriting pretty much all the assets on the asset store and all the code everyone has shared between projects today. I hope you guys realize re-architecturing all this will be a massive amount of work, if you announce the deprecation. I'm sure plenty of people will be up for it, it's new, shiny and exciting. Forcing this rewrite would not be worth it from the rational, economical point of view. Those that want to rewrite and in places where it is appropriate, that's great.
    Performance matters, no question about that. But looking at real projects, most of the frame time is not taken by user scripts (if written properly). They will usually be under 10%, but drilling into it will reveal most of that time is taken by engine calls. Think about what it means to optimize such a small proportion of time compared to the time invested. At some point we will have the option of a rewrite, but that shouldn't be forced by deprecation.

    Besides lacking inheritance, value types have other limitations. The APIs will have to be riddled with refs and ref returns, since copying a large struct on every method call can be expensive too. At MS their tests show these should be under 16 bytes. Further, it seems we won't be able to use any reference type inside the struct itself, except those explicitly defined by the engine (could be wrong here, didn't check). This raises the question of what will happen with strings and non-native collections, and chances are we want to use those.

    I don't know how we would go about using coroutines and events.

    Even if Unity found the way to reduce the boilerplated nature of the system, the maintainability points are subjectively judged. The unit of maintainability is now a system (not a class). There are good points about it. It does seem more testable and more modular, with clearly defined order of operations.
     
    laurentlavigne likes this.
  33. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,363
    Yeah that one was like being at the car dealer: on your left the the beat up car covered in mud, it's got only three wheels but it's cheap, and on the right the one you need to buy.
    The benefit that more honesty would bring is clarity. For example, stresstest showcases blazing performances, we're sold, we don't need another one like that, we need examples that show us simple patterns, like this: https://forum.unity.com/threads/wha...es-would-you-like-to-see.523467/#post-3437926
     
  34. You seriously should read what this thing is really about before you start to guessing. Because you're wrong. Monobehaviours won't be deprecated for a long time. Your codebase is safe for now. You only have to rewrite your OOP-centric code if you want to use these new features. They will be eventually deprecated, but also your codebase will be too old to maintain as well eventually. And you can choose to not to update with every single Unity update as well. But it's not important, you don't have to do anything right now, you can stick to the classic OOP.

    And you're wrong, again, this system actually helps with the 'engine calls' as well. If UE finishes the last leg of this system, the burst compiler. Your code at the end will be machine code. Same level as the Unity code runs.
    Not to mention that writing jobs with the given environment and compiled with the burst compiler, it will be very closely performant as the engine code. With other words, you can write another engine code and use it from your C# codebase, eventually, the border between the engine and your C# code will fade away a little. Especially if UE finished their libraries.

    But, of course, whatever, if you want to use OOP with the classic constructs and components (which are not the same as the entity components), nothing is stopping you, I do not understand your opposition.
     
    KwahuNashoba, Alverik and DwinTeimlon like this.
  35. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Agreed, that's how it came off. The intent with the Classic and Hybrid versions was not to provide any sort of performance comparison, but rather to show how exactly the same game would be made when using hybrid ECS and traditional Unity GameObjects. They were (obviously) reverse-engineered from the Pure version, and I tried to make them as straightforward was possible, but this led to some poor usage of the old systems. I'll look at making the Classic example more reasonable.
     
    JBR-games, Alverik, Gru and 1 other person like this.
  36. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,363
    I figured :D
    Daniel make us another classic vs pure sample that shows off group selection in a gameplay context like "find closest wood bring wood to build site".
    ECS group set operations alone made me take a longer look at ECS.
     
    Last edited: Mar 26, 2018
  37. johnc11

    johnc11

    Joined:
    Jan 18, 2018
    Posts:
    1
    On the boid demo: I get 30 to 35 fps for 200k fish with a 8700k @ 50% utilization. In the late 2016 demo, Joachim was already proud of 30 to 40 fps for only 20k fish. I read somewhere here in the forum about ~10x speedup and that seems to be true. Sick stuff.

    Noob question: When I disable the MeshInstanceRendererSystem, fps snaps to ~95 fps. What's with all the Chunk* related calls in hierarchy which takes up most of the time? Is not optimized yet or expected? Also in general, is there still known but not yet implemented optimization that could further increase utilization other than safety checks etc.?

    // Just noticed when I do a build, utilization goes up to 80%, but fps gets cut in half. Not sure what's the issue there. In editor it runs much better.
     
    Last edited: Mar 26, 2018
  38. Gru

    Gru

    Joined:
    Dec 23, 2012
    Posts:
    142
    I am not trying to create a heated discussion, I am pointing out my opinion about the design decisions of the new system. And yes, I am pro-OOP. I know full well what the new system is about. Reading your post does not clarify any of the points from my post, it restates the existing facts.

    I never said they will be deprecated "right now". I was pointing out the amount of work needed for the whole community to migrate to the new systems. Whatever "for now" means, for example 5 years is too soon. I also pointed out that regardless of when it happens, there are design decisions in the new system that appear limiting from the perspective of the thinking established in the current system.

    Not necessarily.
    It's not just my codebase, there is a large amount of Unity code written in the past years, and it will keep increasing even after the new system is launched.

    Doesn't mean I don't see the benefits of jobs, libraries, native collections and burst. Those things are great. I was talking only about ECS as a full replacement for MBs. I posted: "I recognize the value of this system where there are large amounts of entities."

    Never complained about performance of the Engine code (not here!). Was pointing out that implementing ECS on the user side improves performance of the code that runs a small percentage of the time in most cases compared to the engine code. Don't know what was unclear about that part.

    Never said ECS wasn't good for internal engine code or for user code where it's appropriate (e.g. many agents). I played with the jobs and native collections and have a good grasp on them. Never jabbed any of those systems, they look great.

    My opposition... Well... It seems less convenient for certain scenarios than MBs. It seems like it will need more code and more "copying and juggling things around" if all data types are value types in the end. It seems like it will complicate simpler scenarios, and also the lack of existing features and idioms (coroutines, send message, events, non-native reference types and especially collections, strings...) The emphasis on seems to me, for now.

    Yeah, that makes sense. If I get some time this week I can write my own version and compare the performance and convenience of the systems as it is today, for the purpose of learning the new system. I would share the code and my experience as an act of good will :)

    To point it out, I appreciate the work being done around the new systems, and I hope the design of the ECS can be as pleasant to use as we have gotten used to from Unity in the past. Thanks guys and signing out from this discussion until I get further experience with it.
     
  39. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    Note that the Burst part of this stuff only works in the editor at this point.
     
    johnc11 likes this.
  40. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    So MeshInstanceRendererSystem currently uses quite slow ways of passing the data around. Funnily enough, simulation code is significantly faster than instance rendering now...

    However... when running in build. Burst is not yet supported there... Also rendering speed in player is faster than in editor. So thats why the numbers shift a bit.
     
    MadeFromPolygons and johnc11 like this.
  41. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,980
    Loving the ECS stuff, @Joachim_Ante it might be a good idea to provide a high level document that explains good and bad use cases for the ECS stuff, similar to the sample stuff but essentially just talking about the design choices.

    For instance, a small wave based shooter that will never go over 50 units on screen at once would probably not benefit from porting and would in fact increase difficulty of coding that.

    But a 5000 unit game... probably would benefit greatly!

    lots of units however is an easy to work out case, others less so!
     
    Alverik and andywatts like this.
  42. I am sorry if I came through like someone who actually would like to or heading towards a heated discussion, it is not my intention.
    I think you're overestimating the problem of this thing. And here is why: they don't plan to deprecate MBs any time soon. ECS is great for cases when you need performance or you like to have less battery consumption (these are coming hand in hand). You can choose you either implement the new way of coding or you stick to the abstraction-heavy OOP solutions. If people don't need the performance, people won't migrate. If they need the performance, they will do that. Everyone should decide for themselves if it's a cost-effective move or not.
    I think gradually everyone will make this move and it's because in ECS you can do everything you can in the OOP, but in OOP you can't have a lot of things. For example speed. Somewhere on the forums we already discussed the drawbacks of the over-abstraction in terms of speed and Joachim himself addressed the most problematic corner-stones in his presentations.
    You say that limiting people how to do things is a bad thing and you're favoring OOP? How come? Usually OOP-heavy people are live and die for the coding patterns and the 'right way' to code. Maybe you're an exception.
    Just think about ECS as a coding pattern. Because it is. You can choose if you want to use it or drop it. Again: nothing stops you to do your business otherwise.
    Yes, every coding pattern has limitations and every coding pattern has drawbacks. ECS and the job system have as well (lack of ref types, no abstraction - it is a drawback and a great advantage at the same time).
    I can't see what's wrong with it comparing to any of the main stream OOP pattern.
    Well yeah. It is how software development works. I started in 1998 professionally. I no longer use the majority of my code I have written in the past twenty years. Why? Because we have new ways, better ways, different ways to write a software.
    It will happen with your code as well. And everyone else's as well. No exception. And again, you don't have to convert everything at once, not even in one game. So I don't see the huge problem about this. You can mix and match, you can experiment with separate systems. You can gradually move with your code base. This is how software development works in general.
    No, you mentioned the cost to call in the engine code from the user scripts. And I recognized that and addressed that. Since this system helps that as well. Tightening the two together. And you're missing the point: this system helps not only the user scripts, it helps the engine as well. Moreover the engine code will become the same as a user script. That's the beauty of it. Both will benefit from the move, the engine calls will be cheap, since both will be on the same level with the same language and same optimizations.
    And you can say good bye to all the boxing, marshaling and other unnecessary house-keeping code.
    Well, no, I do not think it will need "more code". Maybe if you count the smaller objects, you will need more small pieces. But if you're doing the OOP right, you aren't too far from it because of the single responsibility principle.
    You shouldn't copying things around. As you're doing in OOP, you should plan how to break down the things you need to do into bite-sized pieces. It is different from the OOP way, naturally, but it is not worse. Do not judge the current state of the system, they have just started, currently it is a heavily hybrid system with a lot of lacking.
    But when you tell me that this system sucks because it is not ready yet, well, okay. I don't see the problem here. When it go to production and these problems aren't addressed somehow, I will join in and grab the torch and the pitch-fork. Until then I will give the benefit of the doubt and can't wait to the delivery date.
    So if it seems to you, and for now, then it is nothing more but baseless guessing. What I was just saying. You are guessing and I think you're wrong.
     
    KwahuNashoba and Alverik like this.
  43. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    Because some paradigm shifts are involved, I think we should still be talking about if, not when.

    If a time ever comes where the current MonoBehaviour way of things, and or other aspects such as gameobjects are declared to be legacy and on the way to being deprecated, then it will be because a whole bunch of concerns including some you mention will have been addresses over time, one way or another.

    And so much detail will have evolved over the years to reach that point, that I find it hard to start talking about such scenarios now. We dont know how quickly ECS will evolve, the extents to which it will catch on, what novel things people may use it for, whether Unity will learn anything along the way that causes any further changes in direction.

    We also dont know what stuff either Unity or 3rd parties may provide to unlock this world of performance for people with varying levels of scripting and programming capabilities. But as just one example, we know Unity see the merits of visual, node graph type programming, and it is not impossible for me to imagine that initiatives on this front or something else may join Jobs, ECS & Burst one day in a manner that really helps the concepts and execution of this type of game programming be understood and harnessed by a wider range of people.

    As for the loss of huge amount of legacy code if the current way of doing things is eventually scrapped, this isnt always a negative, especially if it happens over many years and the rewritten versions offer clear and obvious performance advantages. It's important that this stage of things isnt forced prematurely, but any game engine that spends too long completely shying away from dramatic change is likely to upset people just as much as one that deprecates stuff too quickly. We already have another example of dramatic change with lots of ramifications including not being compatible with lots of shaders & code people wrote for the unity rendering pipeline that we've always had in the past - the new scriptable render pipelines. Again, early days, some very obvious upsides from the get go, along with various things that are not really ready yet and other areas where there are growing pains to be expected. And an area or two where some devs might not be happy, eg something of a paradigm shift in how they are supposed to author shaders for the pipelines, especially if they are asset store devs. We'll see how it goes. I've been lucky so far that I happen to be in a situation where I can be almost universally happy about various new systems in Unity, but I try not to moan too much at people who do express concerns. I am finding myself making 'its way too early to tell, major thing x isnt even ripe yet so its a bit early to panic that Unity have set major thing y as too low a priority for your liking' type posts quite a lot at the moment, and peoples general initial reactions to large changes also has to be factored into the feedback.
     
    Alverik, Gru and Lurking-Ninja like this.
  44. Gru

    Gru

    Joined:
    Dec 23, 2012
    Posts:
    142
    I took a look at the project and did as mentioned. I re-created the project as much as possible, in my own code, first the Classic implementation, then the ECS (Pure) implementation.

    Here is the code: https://bitbucket.org/sirgru/ecs_practice_twinstickshooter

    My Classic implementation doesn't use anything wild, it does what we do today in production projects: it pools, pre-allocates, uses events etc.

    The Jobified version is quite similar to the provided one in Unity's repository. I wanted to keep the features of Classic and Pure on par.

    I also had a Jobified Classic variation but the amount of boilerplate was getting annoying and wasn't getting noticeably better performance so that one isn't published.

    The performance isn't measured very scientifically, I used my FPS counter and observed the framerate ranges. Was more interested in the ballpark measurements, since anything precise is premature for ECS.

    As far as performance on my machine:
    ---------
    My Classic: 790 - 830 FPS
    My Pure: 890 - 920 FPS
    ---------
    Unity's version, and even if I know these weren't meant to be performant but to demonstrate coding practices, it is useful to not expect speedups proportins like below when migrating non-massively parallel projects to current ECS.
    Pure: 700 - 800 FPS
    Classic: 260 - 350 FPS

    ECS API Comments:
    * I was expecting to be able to use inject single IComponentData elements like in the presentation, when we know there’s only 1 of them in the world. However, that gives an error:

    ArgumentException: MySytem:someField [Inject] may only be used on ComponentDataArray<>, ComponentArray<>, TransformAccessArray, EntityArray, GameObjectArray, TransformAccessArray, ComponentArray`1 and int Length.

    This is very inconvenient.

    Worse yet, we must wrap all this injected data into a single struct, and use [Inject] on that.

    From the API point of view, it is better to have direct access to variables then follow these indirections. If we want to group them for convenience or other reasons that could be fine too.

    In the expected use case the current way is most convenient. For system’s state and settings, not so much.

    * The whole API of ComponentSystem assumes we are using arrays, yet it forces us to write the loop ourselves. It could be like IJobParallerFor – for example OnUpdateFor(int index, float deltaTime) can do it. We could have OnPreUpdateFor and OnPostUpdateFor but I assume those would be used less. Combined with the change above, it would make the API even nicer, since we could [Inject] the Length in the base class. This would, of course, work only for 1 “component data group”, but I assume most systems will be like that.

    * In the TransformAccess there is no Forward property, which makes translations harder, and in ECS I’ve only seen position and heading coupling.

    * PostUpdateCommands.SetComponent is strange, it sets the component on something, presumably on the last crated entity? How does it know it’s the entity we just created, and not putting it on something else by mistake? Couldn’t we get the entity handle and set on that?

    * Is Length now a „magic field“? I thought it was the objective to eliminate these “magic members”… If we have this, than we should have “length” also, for those still using the other naming convention.

    * Class math does not follow the naming convention of C#. Types and methods have always been PascalCase in Unity and .NET.

    * Violation of encapsulation becomes obvious when defining what the system applies to. For example, it’s perfectly possible that in a large game the system will select something wrong by accident. At the very least we should force the system to behave only on a certain archetype.

    * I hope Unity will find ways to inject all things we now have static access to. This includes the Time and Input classes. The benefits of this are obvious in testability and determinism. Those should be automatically injected in the base class. Even with injection, Time.deltaTime is so useful it perhaps should be injected in OnUpdate(float deltaTime).

    * Comparing 2 float2s returns a bool2?

    * I was surprised we can’t access PostUpdateCommands from a JobComponentSystem. Was expected a locked queue.

    * Everything seems to be in it’s own separate namespace. I hope namespaces will reconsolidate a bit because things are hard to find.

    * It is so unfortunate bool is not blittable. Perhaps there can be another type like bbool that’s blittable and works just like bool.
    EDIT: Yes it can and here it is:
    Code (CSharp):
    1. struct bbool {
    2.     public byte Value;
    3.  
    4.     public bbool(bool value) {
    5.         Value = (value) ? (byte)1 : (byte)0;
    6.     }
    7.  
    8.     public static implicit operator bbool(bool value) {
    9.         return new bbool(value);
    10.     }
    11.  
    12.     public static implicit operator bool(bbool value) {
    13.         return value.Value == 1;
    14.     }
    15. }
    16.  
    17. public void B(bool b) { }
    18.  
    19. bbool b = true;
    20. B(b);
    21.  
    Further, all provided structs, such as Position and Heading with one field can be modified with
    implicit operator
    to make access more convenient.

    * There should be an API to stick a shared component to the archetype, because sticking it on every instantiated instance seems wrong. It there is one, I haven’t found it.

    * I also found a bug – I would get the error that 2 ComponentDataArrays are the same if they are the same type, even if I know they are different. Duplicating the type to avoid the bug prevented the error. I marked it with a BUG comment in the code if you want to find it.


    Questions:
    * About SetComponentData API… How would we go about if an object has multiple components of the same type? Is that even allowed?

    * Doesn't accessing anything on the system's instance invalidate the cache?


    Nitpicks on the Unity's pure implementation:

    * In the PlayerInputSystem script all players take the same input.

    * This style of saving local state of Random can be problematic. There is a way to create a stateful struct with a long seed and get next randoms by shifting.

    * The pattern used in ShotDamageSystem.cs in CollisionJob is problematic. We are writing to a component data array of shots, in parallel on all the threads the job was split on. Without the [NativeDisableParallelForRestriction] attribute it throws an exception. I think Unity should allow this without the mentioned hacky attribute on [WriteOnly] collections.


    Opinions:
    * The individual systems are smaller, but it becomes harder to reason about all the systems holistically. Every side effect seems like a separate system.

    * ECS is good when there are lots of entities, but most current MBs don’t work on very large amount of entities in real projects.

    * It doesn’t take into account communications between child objects.

    * The now abundant amount of copying around will be decreased when ref returns become available and hopefully with API changes. I wasn’t right about inheritance, since systems are classes and data can be composed, it is possible to emulate current patterns with Inheritance if required.
     
    Last edited: Apr 2, 2018
    Alverik, DeoVolenteGames and Deeeds like this.
  45. FastTurtle222

    FastTurtle222

    Joined:
    Dec 24, 2017
    Posts:
    28
    Any samples on how to animate characters? I have looked over everything the only thing I can find is a wiggle shader, is there not yet a way to animate 3d characters using keyframe animations yet?
     
  46. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,363
    Writing jobs code is like writing shader code, and Mathematics uses shader conventions so everything is designed to pack data and operations in one, wait for it, burst.
     
  47. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    To add to this, I wouldn't be surprised of eventually this math lib is used to write for some kind of C# -> hlsl conversion subset, it's so close to the hlsl function naming.
     
  48. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,363
    Code (CSharp):
    1. [AsyncGPUCompute]
    2. protected override void OnUpdate()
     
  49. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    OHHH.
     
    tigerleapgorge likes this.
  50. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,980
    sure, look into gpu skinning and instanced animations.

    If your not a shader wizard, wait for someone else to release something, 2~3 months minimum
     
    tigerleapgorge likes this.