Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

DOTS and ECS -- I need to modify the ECS implementation. -- Where do I start?

Discussion in 'Entity Component System' started by awesomedata, Aug 21, 2020.

  1. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    I have one question: What do I need to know (and where do I look) to modify the Component portions of ECS?


    I've attempted to modify a package before, but I ended up having to make a duplicate in order to change anything and have it compile, so I'm a bit new at this -- however this is critical for my project.

    That being said, I know ECS is quite deeply integrated with Burst, so I need to know where to look and what stuff I might need to modify (or what stuff I actually _can_ modify) in order to change how the "Component" portion of ECS works with entities. I want to actually make a second KIND of component -- a data-less "Component" -- to attach to all entities that works in parallel to the regular (standard) "data" Component. What scripts are relevant to these two requirements?

    Please don't ask me why I need to do this -- I just need a good overview of what scripts are relevant to making a second version of the Component where I can use (and attach it to GameObjects) in parallel to the standard "Data" Component.


    If you really _must_ know -- I am currently working on a Visual Scripting tool that needs to change ECS to have a "Data" Component and a "Special" Component portion I can attach to GameObjects (and convert at Runtime to Jobs) in order to function properly.

    Where do I start? -- Is there someone I can talk to who knows the ECS implementation in-depth?


    @Joachim_Ante or @mike_acton

    -- Maybe you guys might have a bit more insight on this?

    Unity's Visual Scripting design is in shambles and I feel like I'm the only one who knows how to bridge that gap -- and in a way that nobody else seems to see.

    I'm not afraid of code -- even deep stuff like this -- I just need a foothold on its implementation so I can.
    Let me know if you want me to, and I will PM you with the details if you really need to understand _why_ I need to do this -- but I explain a lot of this in my thread here (if you have time to look it over).
     
    NotaNaN likes this.
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    Don't take this as me agreeing upon your viewpoints of visual scripting. I don't find people to collaborate with enough to even investigate the current visual scripting solutions other than the graphics stuff.

    So for modifying a package, the way I typically do this is I move the package out of the Library/PackageCache into the package folder next to the manifest.json. It has been a while but I think that is all you need to do. If you do it right, there should be a "In Development" tag in the package manager. Note that this is in 2020.1. I've never gotten this workflow to work in 2019 versions. Package development has a really good workflow in 2020.1 though.

    There is a misconception here. The only things you can attach to GameObjects are regular old Components (either built-in or MonoBehaviours). The entities package does not change this. In the GameObjectConversion process, there's really only two things at play: GameObjectConversionSystem and classic GameObject components. Every classical component gets attached to a temporary entity in the GameObjectConversionWorld and the systems' jobs are to copy and write data to a whole different set of entities in a completely different world, often referred to as the "Destination World". You can write custom GameObjectConversionSystems without modifying the Entities package. IConvertGameObjectToEntity is just a scaffold and really there is a GameObjectConversionSystem that iterates through all components, checks if they are an IConvertGameObjectToEntity, and if so, invoke the interface methods. And then [GenerateAuthoringComponent] is just a codegen tool that generates IConvertGameObjectToEntity MonoBehaviours.

    If you have other questions about the code side of things, I'm no expert, but I will try to answer what I can and hopefully others may pitch in as well.
     
    awesomedata and NotaNaN like this.
  3. ThomasEgan

    ThomasEgan

    Joined:
    Dec 17, 2013
    Posts:
    20
    Maybe I'm not really understanding what you're trying to do but the Entities package already allows you to create data-less tag components.

    Code (CSharp):
    1. [GenerateAuthoringComponent]
    2. public struct CustomTag : IComponentData {}
    3.  
    4. public class CustomTagSystem : SystemBase
    5. {
    6.     protected override void OnUpdate()
    7.     {
    8.         Entities.WithAll<CustomTag>().ForEach((Entity e) =>
    9.         {
    10.             // do stuff to entities with CustomTag here
    11.         }).ScheduleParallel();
    12.     }
    13. }
    The GenerateAuthoringComponent attribute creates a monobehaviour CustomTagAuthoring which will add the CustomTag when converted.
    Does this meet your requirements?
     
  4. UsmanMemon

    UsmanMemon

    Joined:
    Jan 24, 2020
    Posts:
    87
    look into Dynamic buffer implementation(since its a component) and see how it works.
     
  5. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    Haha! -- no worries. I won't. (I'm really that bad, eh?) :D


    Anyway, first (since it's faster and really important to my goal here):

    Thanks for that, but I'm aware.

    The "dataless" I'm talking about refers to how Tags are processed behind the scenes (i.e. there's no need to reference their data or "restructure" the entity when they are added/removed -- thus no performance cost when removing "tags").



    I probably need to do this -- If you don't mind, would you please share where/what area I would need to look into to find this?




    Thanks for that -- I was working in 2019.3 so that must be why I'm having such an issue with this.


    Yep -- I was just misremembering the specifics. Thanks for the clarification (and reminder!) -- it was really helpful!


    This would be really awesome! -- Thanks! :)


    To help with this (and clarify some things):

    I refreshed myself on the coding specifics of ECS today (been avoiding this because DOTS is still very preview), just to be sure I was following things properly and it's exactly like you said. Though, I think my case really revolves around the fact that I'm not sure where the "memory allocation" part of the TagComponentData I need.

    My ultimate goal is that I essentially want to duplicate the "Component" to have a variation that allows me to add/remove (dataless) components without any performance impact.

    Ultimately this adding/removing of tags costs a LOT of performance since it has to rebuild the entity's data structure. Therefore I would like to change it to where I have access to all entity tags at once (i.e. a single data structure that will contain "tags" that work like entities -- except they are just binary bits across a larger (byte-based) data structure.
    These would be nothing more than indexes -- but with a user-friendly string for a name (in the editor) I can query from to add/remove tags to entities during the game. These tags would exist regardless of a single entity's _actual_ "data" component's data structure. That "data" component data structure would be the same as it already is -- tags and all -- except I would want to incorporate the more "lightweight" tags for behavioral purposes in my Systems.

    Right now, Unity assumes all my tags would have data references and therefore would require being rebuilt (and thus the performance cost when add/removing them), but I can do one of two things to solve this issue -- I can either do a finite "block" of tag data in bytes (that never changes structure and only flips binary on/off switches for specific tags), OR (as I am currently looking into now) I want to separate this and have separate "tag" and "data" components (to make the previous option less restrictive and still use it, since it seems like a great method to keep things fast). It would be nice to be able to author "data" components in the inspector (and "tag" them in both data structures simultaneously), but data components should have a list of corresponding "tag" components that can be used strictly when running a Query that does not require data retrieval (for Systems to change behavior when a data component's respective "tag" is added/removed, for example). Hopefully this clarifies what I'm after, but if anyone has any questions, please let me know. I've got a lot of digging to do, so I would appreciate if anyone can point me in the right direction for this specifically.

    Either way -- Thanks for your help so far! :)
     
    NotaNaN likes this.
  6. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    JesOb likes this.
  7. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,081
    Hi there :)

    @awesomedata I follow your thoughts about visual scripting and scripting principles at all. Very interesting although hard to read :)

    I think you need to investigate Unity ECS implementation more deeply, because Unity create it to be as performant as it can be.
    @DreamingImLatios last post to enable state for components is one of last parts in ECS that make it suitable for various cases.

    So you can address all type of game behaviour:
    - fast change but slightly more memory consumption : add all needed tags to entities and just enable/disable them to change behaviour
    - slow change but perfect memory consumption : add/remove tag components as they need by gameplay

    Either way will behave exactly the same from systems point of view, and you can change this in late optimisation pass if you wish.

    Heavy operation for restructuring entity is not so heavy as it seems and it there exactly to have best performance for latter processing. enable/disable components will be there exactly for cases where you want to change lot of entities each frame or may be even few times inside frame.

    I have somewhat deep knowledge of C# and Unity so try to help too :)