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

Chunk Utilization with two shared component data

Discussion in 'Entity Component System' started by sebas77, Apr 30, 2019.

  1. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,594
    This is either a bug or me not understanding how ShaderComponentData works yet, even if I read https://gametorrahod.com/everything-about-isharedcomponentdata/ multiple times.

    I use a SharedComponentData with just an integer to group entities. This works well as long as there aren't other SCDs in the PREFAB of the entity (it's the same if I add the sharedcomponent data in the instance, but I put it in the prefab to be even more safe!)

    check this image:

    upload_2019-4-30_13-40-42.png

    in the first case, I have 1 chunk for each entity instance, although the custom shared component data is the same (instances of the same prefab)!

    in all the other cases, where a RenderMesh is not present (no other shared components) it works as expected. I have a chunk for each SharedComponentData permutation (hence each prefab) and N instances in it.

    In the top case I should have had 1 chunk with 23 entities, like in the cases below where I am using instead 3 separate values of the SCD (hence 3 chunks).

    Note: each prefab has different meshes, but instances of the same prefab share the same mesh of course.

    Bug or misunderstanding (which means I cannot use the SCD to group entities)?
     
  2. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,594
    please let me know what you think about it, as I need to understand if using SCD to group entities is a feasible strategy. Because of this inconsistency, I cannot currently use the most optimal code.
     
  3. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Show your code for more info. SCD works as expected, we use it for grouping, without any problems.
     
    Last edited: May 1, 2019
  4. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,594
    Have you tried to use it with a render mesh? I'll create a basic example and post it later today
     
  5. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Of course. And all works as expected.
    Here fast sample - 2 chunks with 4 entities per chunk, which use same RenderMesh but different MySharedComponentData:
    upload_2019-5-1_9-51-17.png
    Code (CSharp):
    1. protected override void OnCreate()
    2.     {
    3.         query = GetEntityQuery(typeof(MyComponentData), typeof(RenderMesh), typeof(MySharedComponentData));
    4.         prefab = EntityManager.CreateEntity(typeof(MyComponentData), typeof(RenderMesh), typeof(MySharedComponentData), typeof(Prefab));
    5.  
    6.         var rm = new RenderMesh()
    7.         {
    8.             mesh = new Mesh(),
    9.             material = new Material(Shader.Find("Standard"))
    10.         };
    11.  
    12.         var mySCD1 = new MySharedComponentData()
    13.         {
    14.             Val = new SomeRefType()
    15.         };
    16.  
    17.         var mySCD2 = new MySharedComponentData()
    18.         {
    19.             Val = new SomeRefType()
    20.         };
    21.  
    22.         for (int i = 0; i < 8; i++)
    23.         {
    24.             var e = EntityManager.Instantiate(prefab);
    25.             EntityManager.SetComponentData(e, new MyComponentData());
    26.             EntityManager.SetSharedComponentData(e, rm);
    27.             EntityManager.SetSharedComponentData(e, (i > 3 ? mySCD1: mySCD2));
    28.         }
    29.     }
    or I can split to 4 chunks with 2 entities in chunk (2 RM 2 MySCD)
    Code (CSharp):
    1. protected override void OnCreate()
    2.     {
    3.         query = GetEntityQuery(typeof(MyComponentData), typeof(RenderMesh), typeof(MySharedComponentData));
    4.         prefab = EntityManager.CreateEntity(typeof(MyComponentData), typeof(RenderMesh), typeof(MySharedComponentData), typeof(Prefab));
    5.  
    6.         var rm1 = new RenderMesh()
    7.         {
    8.             mesh = new Mesh(),
    9.             material = new Material(Shader.Find("Standard"))
    10.         };
    11.      
    12.         var rm2 = new RenderMesh()
    13.         {
    14.             mesh     = new Mesh(),
    15.             material = new Material(Shader.Find("Standard"))
    16.         };
    17.  
    18.         var mySCD1 = new MySharedComponentData()
    19.         {
    20.             Val = new SomeRefType()
    21.         };
    22.      
    23.         var mySCD2 = new MySharedComponentData()
    24.         {
    25.             Val = new SomeRefType()
    26.         };
    27.      
    28.         for (int i = 0; i < 8; i++)
    29.         {
    30.             var e = EntityManager.Instantiate(prefab);
    31.             EntityManager.SetComponentData(e, new MyComponentData());
    32.             EntityManager.SetSharedComponentData(e, (i % 2 == 0 ? rm1: rm2));
    33.             EntityManager.SetSharedComponentData(e, (i > 3 ? mySCD1: mySCD2));
    34.         }
    35.     }
    upload_2019-5-1_9-57-27.png

    Your case only can be if your SCD (not matter your own or RenderMesh) has different references. For example I just create new RM every time in loop:
    upload_2019-5-1_9-54-38.png
     
    Last edited: May 1, 2019
  6. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    As a general rule SharedComponentData should be used for forcing chunking / grouping of entities together.
    The use case is not for storing data. In the case of RenderMesh we use it because it's common to have similar renderers in a scene and pre-batching them together gives big speedups when rendering.

    The unfortunate part is that right now SharedComponentData is also the only thing that can store & serialize an object reference. Something we want to fix by introducing class based components that can hold any managed data type.
     
    Bas-Smit, jdoxbotica and optimise like this.
  7. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,594
    Hello @Joachim_Ante once I understood the mechanism behind the SCD I naturally started to use them for grouping and nothing else. IT works as long as they are not mixed with RenderMeshes. However according @eizenhorn this is not the case, so I will make a simple project later to debug and in case share here.
     
  8. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,029
    When class based components will available?
     
  9. ReadyPlayGames

    ReadyPlayGames

    Joined:
    Jan 24, 2015
    Posts:
    49
    Huh, I didn't know that about SharedComponentData. Makes sense.