Search Unity

Bug when subtract int on IJobParallelFor

Discussion in 'Entity Component System' started by ilyaylm, Apr 4, 2019.

  1. ilyaylm

    ilyaylm

    Joined:
    Aug 20, 2015
    Posts:
    19
    Editor Crash when subtract.
    It is ok for add.
    Am i wrong?

    Code (CSharp):
    1.  struct DamageWork : IJobParallelFor
    2.     {
    3.         [ReadOnly] public EntityCommandBuffer CommandBuffer;
    4.  
    5.         [ReadOnly] public NativeArray<Entity> entities;
    6.  
    7.         [ReadOnly] public ComponentDataFromEntity<DamageTag> damageTag;
    8.         // [ReadOnly] public ComponentDataFromEntity<Damage> otherDamage;
    9.  
    10.         [ReadOnly] public ComponentDataFromEntity<Tag> tag;
    11.  
    12.         [NativeDisableParallelForRestriction]
    13.         public ComponentDataFromEntity<CircleCollision> collision;
    14.         [NativeDisableParallelForRestriction]
    15.         public ComponentDataFromEntity<HealthPoint> healthPoint;
    16.         [NativeDisableParallelForRestriction] public ComponentDataFromEntity<Damage> otherDamage;
    17.  
    18.         public void Execute(int index)
    19.         {
    20.          CircleCollision receiverCol = collision[entities[index]];
    21.  
    22.             if (collision[entities[index]].hit)
    23.             {
    24.                 Enum_Tag otherTag = tag[receiverCol.hitEntity].Value;
    25.                 Enum_Tag damagableFromTag = damageTag[entities[index]].DamagableFromTag;
    26.                 bool match = false;
    27.  
    28.                 if (damagableFromTag == otherTag)
    29.                 {
    30.                     match = true;
    31.                 }
    32.              
    33.                 //--------------------------------------------------------------------------------------------------
    34.                 //Look Here
    35.                 //--------------------------------------------------------------------------------------------------
    36.                 if (match)
    37.                 {
    38. //NOT CRASH when add
    39.                     healthPoint[entities[index]] = new HealthPoint(healthPoint[entities[index]].Value + 1);
    40. //CRASH when subsract
    41.                     healthPoint[entities[index]] = new HealthPoint(healthPoint[entities[index]].Value - 1);
    42.                    
    43.                     receiverCol.hitEntity = Entity.Null;
    44.                 }
    45.                 //--------------------------------------------------------------------------------------------------
    46.  
    47.             }
    48.  
    49.         }
    50.     }
     
  2. ilyaylm

    ilyaylm

    Joined:
    Aug 20, 2015
    Posts:
    19
    I found the problem.
    This is dependency problem or job order.
    My flow is like this
    > Do Collision Check (Collision System)
    > Do Damage Check (Damage System)
    > Do Destroy Check (Destroy System)

    I don't know how Execution order work in internal System, but while DamageSystem doing it's job DestroySystem delete the entity. And Damage System still access to deleted entity. That's why crashed.

    So, i've done like this

    Code (CSharp):
    1.  protected override JobHandle OnUpdate(JobHandle inputDeps)
    2.     {
    3.         var DamageWorkJob = new DamageWork
    4.         {
    5.            damageTag = GetComponentDataFromEntity<DamageTag>(),
    6.             otherDamage = GetComponentDataFromEntity<Damage>(),
    7.             tag = GetComponentDataFromEntity<Tag>()
    8.         };
    9.         var DamageWorkJobbHandle = DamageWorkJob.Schedule(this, inputDeps);
    10.        
    11.         var job = new Destroy
    12.         {
    13.             CommandBuffer = m_ECB.CreateCommandBuffer(),
    14.  
    15.         }.ScheduleSingle(this, DamageWorkJobbHandle);
    16.         job.Complete();
    17.         return job;
    18.  
    19.     }
    But stil crashed. So add "DamageWorkJobbHandle.Complete();". Now it works well.

    Code (CSharp):
    1.  protected override JobHandle OnUpdate(JobHandle inputDeps)
    2.     {
    3.         var DamageWorkJob = new DamageWork
    4.         {
    5.            damageTag = GetComponentDataFromEntity<DamageTag>(),
    6.             otherDamage = GetComponentDataFromEntity<Damage>(),
    7.             tag = GetComponentDataFromEntity<Tag>()
    8.         };
    9.         var DamageWorkJobbHandle = DamageWorkJob.Schedule(this, inputDeps);
    10.        DamageWorkJobbHandle.Complete();
    11.         var job = new Destroy
    12.         {
    13.             CommandBuffer = m_ECB.CreateCommandBuffer(),
    14.  
    15.         }.ScheduleSingle(this, DamageWorkJobbHandle);
    16.         job.Complete();
    17.         return job;
    18.  
    19.     }