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

Question Are there any problems making multiple IInputComponentData per entity (Player)?

Discussion in 'NetCode for ECS' started by OrientedPain, Aug 15, 2023.

  1. OrientedPain

    OrientedPain

    Joined:
    Mar 26, 2018
    Posts:
    37
    Hello everyone,

    As what I learned from DOTS best practice, the recommended approach is to have many small components with fewer properties rather than a few large components with many properties.

    By breaking down data into smaller components, I can ensure that the ECS only processes the necessary data for each system, reducing memory overhead and improving overall efficiency also I can consider what to be replicated or not.

    Does IInputComponentData same as any other components (i.e. IComponentData) that I can the bove approach apply on?


    So, which is better when using IInputComponentData:

    Code (CSharp):
    1. [GhostComponent(PrefabType = GhostPrefabType.AllPredicted, OwnerSendType = SendToOwnerType.SendToNonOwner)]
    2. public struct PlayerMovementInputs : IInputComponentData
    3. {
    4.     public int Horizontal;
    5.     public int Vertical;
    6. }
    7.  
    8. public struct PlayerCameraInputs : IInputComponentData
    9. {
    10.     public float Pitch;
    11.     public float Yaw;
    12. }
    13.  
    14. public struct PlayerAttackInputs : IInputComponentData
    15. {
    16.     public InputEvent SkillAttack;
    17. }
    OR......

    Code (CSharp):
    1. [GhostComponent(PrefabType = GhostPrefabType.AllPredicted, OwnerSendType = SendToOwnerType.SendToNonOwner)]
    2. public struct PlayerInputs : IInputComponentData
    3. {
    4.     public int Horizontal;
    5.     public int Vertical;
    6.     public InputEvent SkillAttack;
    7.     public float Pitch;
    8.     public float Yaw;
    9. }
    10.  
    Thanks in advance.
     
  2. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    774
    Breaking down IComponentData into multiple pieces has very little benefits. Actually, it increase the complexity (you are adding more buffer and serialisation/deserialisation costs) and may be just slower.

    The inputcomponent data is present usually on the player entity. That are not many. And probably used only for predicting your own player movement too (so 1 entity).
    Any component data fetch is also at least 64 bytes anyway, so having something smaller than that, unless you are processing batch of entities, is somewhat not optimal either.

    Good ECS practice is not just making component small, same goes for jobs and systems work. There are costs associated with all of these.
    But speaking about data, reasoning in term of "data locality" and what is used together usually end up with the best design. Splitting component in very small individual pieces as also limit in term of cache efficiency, based on the way of the cache (usually 8). Reading more and more stream, of data, may end up anyway to trash cache lines (of course need to be measured).

    From a replication perspective, Netcode work best with "fat" components, instead of a plethora of small ones.
    So it is more a trade-off and balancing factor.
     
    OrientedPain likes this.
  3. OrientedPain

    OrientedPain

    Joined:
    Mar 26, 2018
    Posts:
    37
    Thank you for your valuable response.
     
  4. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,029
    Is that the IComponentData u mention not just applies to IInputComponentData but also ghost IComponentData that has [GhostField] tag and also regular IComponentData without [GhostField] tag? If yes, so that's why now Entities transform system now combined position, rotation and scale together into one single LocalTransform component?
     
  5. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    774
    This applies to all components in general. Combining transform together in one component was also to simplify certain access scenario, yes. But there was other reasoning behind that choice.