Search Unity

Bug I try to fix the message "A Native collection has not been disposed" but i can't

Discussion in 'C# Job System' started by yackson-cc, May 23, 2023.

  1. yackson-cc

    yackson-cc

    Joined:
    May 14, 2016
    Posts:
    48
    Hi, please, what is the error here:

    Code (CSharp):
    1. public class JobsToMoveAndRotateUnits : Singleton<JobsToMoveAndRotateUnits>
    2.    {
    3.       [ReadOnly]
    4.       private NativeArray<float3> nativeArrayOwnerUnitPosition;
    5.  
    6.       private TransformAccessArray transformAccessArrayUnit;
    7.  
    8.       private NativeArray<float> nativeArraySpeedNormalized;
    9.  
    10.       [SerializeField]
    11.       private List<Transform> listTransformOwnerUnit;
    12.  
    13.       [SerializeField]
    14.       private List<Transform> listTransformUnit;
    15.  
    16.       [SerializeField]
    17.       private float lenghtToNormalizeMovementLenght = 1f;
    18.  
    19.       [SerializeField]
    20.       private float speedPositionInterpolation;
    21.  
    22.       [SerializeField]
    23.       private float speedRotationInterpolation;
    24.  
    25.       private JobHandle jobHandleMovement;
    26.  
    27.       private void Update()
    28.       {
    29.          nativeArrayOwnerUnitPosition = new NativeArray<float3>(listTransformUnit.Count, Allocator.Persistent);
    30.  
    31.          for(int i = 0; i < listTransformOwnerUnit.Count; i++)
    32.             nativeArrayOwnerUnitPosition[i] = listTransformOwnerUnit[i].position;
    33.  
    34.          transformAccessArrayUnit = new TransformAccessArray(listTransformUnit.ToArray());
    35.          nativeArraySpeedNormalized = new NativeArray<float>(listTransformUnit.Count, Allocator.Persistent);
    36.  
    37.          var tmpJobMovementTransforms = new MoveUnits()
    38.                                         {
    39.                                            deltaTime = Time.deltaTime,
    40.                                            lenghtToNormalizeMovementLenght = lenghtToNormalizeMovementLenght,
    41.                                            nativeArraySpeedNormalized = nativeArraySpeedNormalized,
    42.                                            speedPositionInterpolation = speedPositionInterpolation,
    43.                                            speedRotationInterpolation = speedRotationInterpolation,
    44.                                            nativeArrayOwnerUnitPosition = nativeArrayOwnerUnitPosition
    45.                                         };
    46.  
    47.          jobHandleMovement = tmpJobMovementTransforms.Schedule(transformAccessArrayUnit);
    48.          jobHandleMovement.Complete();
    49.       }
    50.  
    51.       public int AddUnit(Transform argTransformOwnerUnit, Transform argTransformUnit)
    52.       {
    53.          var tmpIndexWhereUnitWasAdded = listTransformUnit.Count;
    54.          listTransformUnit.Add(argTransformUnit);
    55.          listTransformOwnerUnit.Add(argTransformOwnerUnit);
    56.          return tmpIndexWhereUnitWasAdded;
    57.       }
    58.  
    59.       public void RemoveUnit(Transform argTransformOwnerUnit, Transform argTransformUnit)
    60.       {
    61.          listTransformUnit.Remove(argTransformUnit);
    62.          listTransformOwnerUnit.Remove(argTransformOwnerUnit);
    63.       }
    64.  
    65.       public float GetMovementSpeedNormalizedOfUnitId(int argUnitIDInJobsToMoveAndRotateUnits)
    66.       {
    67.          return nativeArraySpeedNormalized[argUnitIDInJobsToMoveAndRotateUnits];
    68.       }
    69.    }
    70.  
    71.    [BurstCompile]
    72.    public struct MoveUnits : IJobParallelForTransform
    73.    {
    74.       [ReadOnly]
    75.       public NativeArray<float3> nativeArrayOwnerUnitPosition;
    76.  
    77.       public float deltaTime;
    78.  
    79.       public float speedPositionInterpolation;
    80.  
    81.       public float speedRotationInterpolation;
    82.  
    83.       public float lenghtToNormalizeMovementLenght;
    84.  
    85.       public NativeArray<float> nativeArraySpeedNormalized;
    86.  
    87.       public void Execute(int index, TransformAccess transform)
    88.       {
    89.          float3 tmpPositionUnit = transform.position;
    90.          float3 tmpDirectionXYZ = nativeArrayOwnerUnitPosition[index] - tmpPositionUnit;
    91.          float2 tmpDirectionXZ = new float2(tmpDirectionXYZ[0], tmpDirectionXYZ[2]);
    92.          float tmpLengthDirectionXZ = math.length(tmpDirectionXZ);
    93.          nativeArraySpeedNormalized[index] = tmpLengthDirectionXZ / lenghtToNormalizeMovementLenght;
    94.  
    95.          float3 tmpPositionLerp = math.lerp(tmpPositionUnit, nativeArrayOwnerUnitPosition[index], speedPositionInterpolation * deltaTime);
    96.          quaternion tmpRotationUnit = transform.rotation;
    97.  
    98.          if(tmpLengthDirectionXZ > 0.001f)
    99.          {
    100.             tmpDirectionXZ = math.normalize(tmpDirectionXZ);
    101.             quaternion tmpRotationSlerp = math.slerp(tmpRotationUnit, quaternion.LookRotation(new float3(tmpDirectionXZ[0], 0, tmpDirectionXZ[1]), new float3(0, 1, 0)), speedRotationInterpolation * deltaTime);
    102.             transform.SetPositionAndRotation(tmpPositionLerp, tmpRotationSlerp);
    103.          }
    104.          else
    105.             transform.position = tmpPositionLerp;
    106.       }
    107.    }
    I try to dispose all nativeArrays in OnDisabled(), but no fix the error in console:

    Is weird because the the game works well.

    upload_2023-5-22_19-22-59.png
     
  2. brunocoimbra

    brunocoimbra

    Joined:
    Sep 2, 2015
    Posts:
    679
    You are allocating a new one each frame (on Update), instead of either creating a new one on Awake/OnEnable/Start or using Allocator.Temp/TempJob instead of Persistent
     
  3. yackson-cc

    yackson-cc

    Joined:
    May 14, 2016
    Posts:
    48
    @brunocoimbra Thanks bro, i have a dude please, when do I must use Persistent or Temp?
    i can update the values in persistent? or temp was created to it?
     
  4. brunocoimbra

    brunocoimbra

    Joined:
    Sep 2, 2015
    Posts:
    679
    You can change the values but can't resize it without re-allocating.

    There is no golden rule, but usually you want Temp/TempJob when the data don't need any persistence outside a specific scope or job, and Persistent when you need to cache the data to use outside said specific scope or job.
     
  5. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,975
    That isn‘t weird at all. The logic may be sound but you are leaking memory. You will only see the detrimental effect over time as your app grows in memory usage and eventually crashes.