Search Unity

EntityCommandBuffer playback bug?

Discussion in 'Entity Component System' started by Richay, Mar 15, 2020.

  1. Richay

    Richay

    Joined:
    Aug 5, 2013
    Posts:
    122
    I'm encountering occasional ECB playback errors.

    In my system, I'm instantiating prefab entities in one job, and then adding components to the instantiated entities via other jobs (to keep jobs separate instead of having a huge collection of CDFE values).

    About 20% of the time that this code executes, I have this error:

    Code (CSharp):
    1. ArgumentException: Invalid Entity version
    2. EntityCommandBuffer was recorded in Interactables.SpawnPrefabSystem and played back in Unity.Entities.EndSimulationEntityCommandBufferSystem.
    I have tried adding the optional components using both the job entityInQueryIndex and the entityInQueryIndex of the instantiating job (as shown below, in case the ECB entity remapping depended on this).

    The strangest thing is that the error does not occur 100% of the time, which suggests that it is a timing error, although I cannot see what it might be, and thus I feel that it may be a bug in the ECB playback system.

    Code (CSharp):
    1. internal class SpawnPrefabSystem : CommandSystemBase
    2. {
    3.     private EntityQuery m_Query;
    4.     private NativeMultiHashMap<Entity, Value> m_Map;
    5.    
    6.     private struct Value
    7.     {
    8.         public int Index;
    9.         public Entity Entity;
    10.     }
    11.  
    12.     protected override void OnCreateInternal()
    13.     {
    14.         RequireForUpdate(m_Query);
    15.         m_Map = new NativeMultiHashMap<Entity, Value>(1000, Allocator.Persistent);
    16.     }
    17.  
    18.     protected override void OnDestroy()
    19.     {
    20.         m_Map.Dispose();
    21.     }
    22.  
    23.     protected override void OnUpdate()
    24.     {
    25.         // CommandBufferSystem is EndSimulationEntityCommandBuffer.
    26.         var commandBuffer = CommandBufferSystem.CreateCommandBuffer().ToConcurrent();
    27.  
    28.         m_Map.Clear();
    29.         var map = m_Map;
    30.         var writer = map.AsParallelWriter();
    31.  
    32.         // Instantiate new entities, and add to a native multi hashmap.
    33.         Entities
    34.             .ForEach((Entity entity, int entityInQueryIndex, in SpawnPrefabData spawnData,
    35.                 in SpawnPrefabFixedQuantityData quantityData, in Translation translation) =>
    36.             {
    37.                 for (int i = 0; i < quantityData.Quantity; i++)
    38.                 {
    39.                     var instanceEntity = commandBuffer.Instantiate(entityInQueryIndex, spawnData.PrefabEntity);
    40.                     commandBuffer.AddComponent(entityInQueryIndex, instanceEntity, new Translation { Value = translation.Value });
    41.  
    42.                     writer.Add(entity, new Value { Index = entityInQueryIndex, Entity = instanceEntity });
    43.                 }
    44.             })
    45.             .Schedule();
    46.  
    47.         // Add components to instantiated entities based on optional components on the spawner entity.
    48.         Entities
    49.             .WithReadOnly(map)
    50.             .WithAll<SpawnPrefabData>()
    51.             .ForEach((Entity entity, int entityInQueryIndex, in ApplyForceOnSpawnData forceData) =>
    52.             {
    53.                 if (map.ContainsKey(entity))
    54.                 {
    55.                     var values = map.GetValuesForKey(entity);
    56.                     while (values.MoveNext())
    57.                     {
    58.                         var value = values.Current;
    59.  
    60.                         commandBuffer.AddComponent(value.Index, value.Entity, new PhysicsVelocity
    61.                         {
    62.                             Linear = forceData.ForceDirection * forceData.Force
    63.                         });
    64.                     }
    65.                 }
    66.             })
    67.             .Schedule();
    68.  
    69.         // Delete spawner entities.
    70.         Entities
    71.             .WithStoreEntityQueryInField(ref m_Query)
    72.             .WithAll<SpawnPrefabData>()
    73.             .ForEach((Entity entity, int entityInQueryIndex) =>
    74.             {
    75.                 commandBuffer.DestroyEntity(entityInQueryIndex, entity);
    76.             })
    77.             .Schedule();
    78.  
    79.         CommandBufferSystem.AddJobHandleForProducer(Dependency);
    80.     }
    81. }
     
  2. NinhNv15

    NinhNv15

    Joined:
    Jan 31, 2016
    Posts:
    6
    I got same error. Did you find problem and solution for this bug?
     
  3. Richay

    Richay

    Joined:
    Aug 5, 2013
    Posts:
    122
    No sorry, this is from 2.5 years ago, I hope/assume it's been fixed since then.