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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

How do you properly get unique instances of ISharedComponentData?

Discussion in 'Entity Component System' started by davenirline, Jul 23, 2018.

  1. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    942
    I tried EntityManager.GetAllUniqueSharedComponentDatas() but it's weird that I'm getting one even when I haven't made any. Then on the next frame, it becomes 2, then 3, and so on. Why is it increasing?
     
  2. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    804
    As to your question of how it keeps increasing, I think that you need to clear your List at the end of the OnUpdate() or before calling EntityManager.GetAllUniqueSharedComponentDatas() again. (I'm guessing that you are calling ot from OnUpdate)

    I am having a similar issue where it returns more than 1 when it's only attached to 1 GameObject. Here are some simple test code I created that shows the issue.

    Code (CSharp):
    1. [System.Serializable]
    2. public struct TestData : ISharedComponentData
    3. {
    4.     //Returns 2
    5.     //public Object value;
    6.     //Returns 2
    7.     //public string value;
    8.     //Returns 1
    9.     //public int value;
    10.     //Returns1
    11.     public bool value;
    12. }
    13.  
    14. public class TestComponent : SharedComponentDataWrapper<TestData> { }
    Code (CSharp):
    1. public class TestSystem : ComponentSystem
    2. {
    3.     private readonly List<TestData> cachedTestData = new List<TestData>(3);
    4.     private ComponentGroup componentGroup;
    5.  
    6.     protected override void OnCreateManager(int capacity)
    7.     {
    8.         componentGroup = GetComponentGroup(typeof(TransformMatrix), typeof(TestData));
    9.     }
    10.  
    11.     protected override void OnUpdate()
    12.     {
    13.         EntityManager.GetAllUniqueSharedComponentDatas(cachedTestData);
    14.         Debug.Log("cachedUniqueSharedSpriteRenderer: " + cachedTestData.Count);
    15.  
    16.         for (int i = 0; i != cachedTestData.Count; i++)
    17.         {
    18.             TestData testData = cachedTestData[i];
    19.             if (testData.value == null)
    20.             {
    21.                 Debug.Log("Index: " + i + " is null");
    22.                 continue;
    23.             }
    24.             Debug.Log("Index: " + i + " is not null");
    25.         }
    26.  
    27.         cachedTestData.Clear();
    28.     }
    29. }
    Does anyone know why with some type fields the count it returns is not the same?
     
  3. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    942
    I see. That's good to know.

    There's still one weird behaviour. Why do I get one instance even if I haven't called any AddSharedComponentData()?
     
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,624
    It always seems to include the default instance. You can start indexing at 1 to skip it if you need (usually it doesn't matter).
     
  5. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    804
    That won't work. If I run the code that is posted above attached to a single entity it returns the count as 1 (correct value), but if I change the type of value to either string or any Object based type. It will return the count as 2 (while the Entity Debug still only points to 1 Entity).
     
  6. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,624
    I'm not really sure what you just said to be honest.

    What I suggested is exactly what Unity does in their own demos.

    https://github.com/Unity-Technologi...s/Assets/GameCode/Samples.Boids/BoidSystem.cs

    Code (CSharp):
    1.             EntityManager.GetAllUniqueSharedComponentDatas(m_UniqueTypes);
    2.        
    3.             var obstaclePositions = m_ObstacleGroup.GetComponentDataArray<Position>();
    4.             var targetPositions   = m_TargetGroup.GetComponentDataArray<Position>();
    5.        
    6.             // Ingore typeIndex 0, can't use the default for anything meaningful.
    7.             for (int typeIndex = 1; typeIndex < m_UniqueTypes.Count; typeIndex++)
    8.             {
    They skip index 0 because it's mostly meaningless

    GetAllUniqueSharedComponentDatas returns all SharedComponentDatas + default(T) which is always index 0
     
  7. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,151
    I think this has something to do with the wrapper. If you remove the wrapper and load the reference some way other than the inspector (as obviously you cannot use the inspector if you get rid of the wrapper), does the count go back down to 1?