Search Unity

Data in NativeArray Reverting to Default Value after RemoveComponent

Discussion in 'Entity Component System' started by Ronnie_0, Dec 20, 2019.

  1. Ronnie_0

    Ronnie_0

    Joined:
    Oct 3, 2011
    Posts:
    34
    I'm attempting to use a job (AssignValue) to store some data in a NativeArray. However, when I use the structure below, it seems like my stored data is being reverted to its default value after I remove the component in AssignValue.

    In the first frame, the code will print to the console the correct value (15), but the next frame the value is reverted to 0. If I comment out the _commandBuffer.RemoveComponent... line, I get the results I expect (15 on every frame).

    Any guidance towards why this is happening or a work-around would be much appreciated!

    Code (CSharp):
    1. public struct TagA : IComponentData { }
    2. public struct TagB : IComponentData { }
    3. public struct FooComp : IComponentData
    4. {
    5.     public int FooValue;
    6. }
    Code (CSharp):
    1. public class BarSystem : JobComponentSystem
    2. {
    3.     private EndSimulationEntityCommandBufferSystem _endSim;
    4.  
    5.     protected override void OnCreate()
    6.     {
    7.         _endSim = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    8.     }
    9.  
    10.     private struct AssignValue : IJobForEachWithEntity<TagA, FooComp>
    11.     {
    12.         private NativeArray<FooComp> _fooComps;
    13.         private EntityCommandBuffer.Concurrent _commandBuffer;
    14.  
    15.         public AssignValue(
    16.             NativeArray<FooComp> fooComps,
    17.             EntityCommandBuffer.Concurrent commandBuffer)
    18.         {
    19.             _fooComps = fooComps;
    20.             _commandBuffer = commandBuffer;
    21.         }
    22.        
    23.         public void Execute(
    24.             Entity entity,
    25.             int index,
    26.             [ReadOnly] ref TagA tagA,
    27.             ref FooComp fooComp)
    28.         {
    29.             // _fooComps[0] = fooComp;                                  // Nope
    30.             // _fooComps[0] = new FooComp{FooValue = fooComp.FooValue}; // Nope
    31.             _fooComps[0] = new FooComp{FooValue = 15};                  // Nope
    32.             _commandBuffer.RemoveComponent<FooComp>(index, entity);
    33.         }
    34.     }
    35.    
    36.     private struct Print : IJobForEachWithEntity<TagB>
    37.     {
    38.         [DeallocateOnJobCompletion] private NativeArray<FooComp> _fooComps;
    39.  
    40.         public Print(
    41.             NativeArray<FooComp> fooComps)
    42.         {
    43.             _fooComps = fooComps;
    44.         }
    45.        
    46.         public void Execute(
    47.             Entity entity,
    48.             int index,
    49.             [ReadOnly] ref TagB tagB)
    50.         {
    51.             Debug.Log(_fooComps[0].FooValue);
    52.         }
    53.     }
    54.  
    55.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    56.     {
    57.         var fooComps = new NativeArray<FooComp>(1, Allocator.TempJob);
    58.        
    59.         var assignJob = new AssignValue(
    60.             fooComps,
    61.             _endSim.CreateCommandBuffer().ToConcurrent());
    62.         var printJob = new Print(fooComps);
    63.  
    64.         var assignHandle = assignJob.Schedule(this, inputDeps);
    65.         var printHandle = printJob.Schedule(this, assignHandle);
    66.        
    67.         _endSim.AddJobHandleForProducer(assignHandle);
    68.  
    69.         return printHandle;
    70.     }
    71. }
    Code (CSharp):
    1. public class Post : MonoBehaviour
    2. {
    3.     private void Start()
    4.     {
    5.         var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
    6.  
    7.         var entityA = entityManager.CreateEntity(
    8.             typeof(TagA),
    9.             typeof(FooComp));
    10.         entityManager.SetComponentData(entityA, new FooComp{FooValue = 15});
    11.  
    12.         entityManager.CreateEntity(typeof(TagB));
    13.     }
    14. }