Search Unity

TransformAccessArray from RectTransform

Discussion in 'Entity Component System' started by GilCat, Nov 7, 2018.

  1. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    Hello
    Is there a way for accessing the transform array using GetTransformAccessArray() of ComponentGroup?
    Right now i'm doing it like:
    Code (CSharp):
    1.     var transformArray = new TransformAccessArray(m_group.GetComponentArray<RectTransform>().ToArray());
    2.     inputDeps = new MyJob().Schedule(transformArray, inputDeps);
    3.     transformArray.Dispose();
    But this seems to be much more expensive than GetTransformAccessArray() where i don't even need to dispose the array in the end.

    Thanks
     
  2. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    166
    I has the same question,has you solve?
     
  3. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    No i haven't!
    I don't think there will be anything on this because the way forward is to go Pure ECS discarding the need for this.
     
  4. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    166
    This my function to solve:
    Code (CSharp):
    1. public TransformAccessArray GetTransformAccessArray(ComponentGroup group)
    2.         {
    3.             EntityManager entityManager = EntityManager;
    4.             int orderVersion = entityManager.GetComponentOrderVersion<RectTransform>();
    5.             if (orderVersion == __orderVersion)
    6.                 return __transformAccessArray;
    7.  
    8.             __orderVersion = orderVersion;
    9.  
    10.             ComponentArray<RectTransform> trans = group.GetComponentArray<RectTransform>();
    11.             if (!__transformAccessArray.isCreated)
    12.                 __transformAccessArray = new TransformAccessArray(trans.ToArray(), -1);
    13.             else
    14.                 __transformAccessArray.SetTransforms(trans.ToArray());
    15.            
    16.             return __transformAccessArray;
    17.         }
     
    GilCat likes this.
  5. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    The problem with that function and similar ways of retrieving the TransformAccessArray is that it generates garbage and we can't do it in a job (i think). By profiling it against GetTransformAccessArray() directly there is a ~10X performance hit.
    By looking at the code i could see that it is implemented in TransformAccessArrayIterator.cs and it looks like this:
    Code (CSharp):
    1. public static unsafe TransformAccessArray GetTransformAccessArray(this ComponentGroup group)
    2.         {
    3.             var state = (TransformAccessArrayState?)group.m_CachedState ?? new TransformAccessArrayState();
    4.             var orderVersion = group.EntityDataManager->GetComponentTypeOrderVersion(TypeManager.GetTypeIndex<Transform>());
    5.  
    6.             if (state.Data.isCreated && orderVersion == state.OrderVersion)
    7.                 return state.Data;
    8.  
    9.             state.OrderVersion = orderVersion;
    10.  
    11.             UnityEngine.Profiling.Profiler.BeginSample("DirtyTransformAccessArrayUpdate");
    12.             var trans = group.GetComponentArray<Transform>();
    13.             if (!state.Data.isCreated)
    14.                 state.Data = new TransformAccessArray(trans.ToArray());
    15.             else
    16.                 state.Data.SetTransforms(trans.ToArray());
    17.             UnityEngine.Profiling.Profiler.EndSample();
    18.  
    19.             group.m_CachedState = state;
    20.  
    21.             return state.Data;
    22.         }
    So i went there and created a version for RectTransform and it works pretty good:
    Code (CSharp):
    1. public static unsafe TransformAccessArray GetRectTransformAccessArray(this ComponentGroup group) {
    2.       var state = (TransformAccessArrayState?)group.m_CachedState ?? new TransformAccessArrayState();
    3.       var orderVersion = group.EntityDataManager->GetComponentTypeOrderVersion(TypeManager.GetTypeIndex<RectTransform>());
    4.  
    5.       if (state.Data.isCreated && orderVersion == state.OrderVersion)
    6.         return state.Data;
    7.  
    8.       state.OrderVersion = orderVersion;
    9.  
    10.       UnityEngine.Profiling.Profiler.BeginSample("DirtyRectTransformAccessArrayUpdate");
    11.       var trans = group.GetComponentArray<RectTransform>();
    12.       if (!state.Data.isCreated)
    13.         state.Data = new TransformAccessArray(trans.ToArray());
    14.       else
    15.         state.Data.SetTransforms(trans.ToArray());
    16.       UnityEngine.Profiling.Profiler.EndSample();
    17.  
    18.       group.m_CachedState = state;
    19.  
    20.       return state.Data;
    21.     }
    The problem is that i can only create this inside the package and can't create an extension in my side due to it accessing some internals.
    @Joachim_Ante Is there any trick to have this working? If not could it be added to next release?
    This is very useful right now for using UI elements from Unity UI at least until we have a pure ECS solution.

    Thanks