Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Enter the 2020.2 Beta Sweepstakes for a chance to win an Oculus Quest 2.
    Dismiss Notice

[SOLVED] Error in previously working code. Need [ReadOnly] attrib, but where?

Discussion in 'Data Oriented Technology Stack' started by JamesWjRose, Sep 10, 2020.

  1. JamesWjRose

    JamesWjRose

    Joined:
    Apr 13, 2017
    Posts:
    476
    So... a couple of months ago I had to stop working on my game and do other things, among them reformat and reinstall everything on my dev machine. I updated to the most recent version of Unity (2020.1.4f1) and the latest versions of DOTS. Now I am getting the following error mentioning that I need to set an object to ReadOnly. Cool, fine, sure... which one?!

    Code (CSharp):
    1.  
    2. InvalidOperationException: The ComponentDataFromEntity<RoadDetails> <>c__DisplayClass_OnUpdate_LambdaJob0.JobData.RoadDetailsFromEntity must be marked [ReadOnly] in the job ER3D_TrafficSystem:<>c__DisplayClass_OnUpdate_LambdaJob0, because the container itself is marked read only.
    3.  
    4. Unity.Entities.JobChunkExtensions.FinalizeScheduleChecked (System.Boolean isParallel, System.Int32 unfilteredChunkCount, Unity.Jobs.JobHandle prefilterHandle, Unity.Collections.NativeArray`1[T] prefilterData, System.Void* deferredCountData, System.Boolean useFiltering, Unity.Jobs.LowLevel.Unsafe.JobsUtility+JobScheduleParameters& scheduleParams, System.Boolean& executed, Unity.Jobs.JobHandle& result) (at Library/PackageCache/com.unity.entities@0.14.0-preview.18/Unity.Entities/IJobChunk.cs:270)
    5. Unity.Entities.JobChunkExtensions.ScheduleInternal[T] (T& jobData, Unity.Entities.EntityQuery query, Unity.Jobs.JobHandle dependsOn, Unity.Jobs.LowLevel.Unsafe.ScheduleMode mode, System.Boolean isParallel) (at Library/PackageCache/com.unity.entities@0.14.0-preview.18/Unity.Entities/IJobChunk.cs:246)
    6. Unity.Entities.JobChunkExtensions.ScheduleSingle[T] (T jobData, Unity.Entities.EntityQuery query, Unity.Jobs.JobHandle dependsOn) (at Library/PackageCache/com.unity.entities@0.14.0-preview.18/Unity.Entities/IJobChunk.cs:131)
    7. ER3D_TrafficSystem.OnUpdate () (at Assets/HBC/Scripts/ER3D_TrafficSystem.cs:49)
    8.  
    Ok, so it's talking about line 49 (see the entire class below) and specifically this line:
    Code (CSharp):
    1. RoadDetails roadDetails = RoadDetailsFromEntity[roads[i]];
    at line 79. I know this because if I comment it out, the code runs without error (not completely true, it moves on to screaming about the same issue with ConnectionDetailsFromEntity, but you get my point)

    Within the OnUpdate there are the declarations for the ...FromEntity", however when I attempt to place a "[ReadOnly]" attribute, that too screams at me.

    So... what changed with the process and does anyone care to point me in the right direction?

    Thank you very much.

    Code (CSharp):
    1. using Unity.Burst;
    2. using Unity.Collections;
    3. using Unity.Entities;
    4. using Unity.Jobs;
    5. using Unity.Mathematics;
    6. using Unity.Transforms;
    7. using UnityEngine;
    8.  
    9. public class ER3D_TrafficSystem : SystemBase
    10. {
    11.     private NativeArray<Entity> roadEntities;
    12.     private NativeArray<Entity> connectionEntities;
    13.    
    14.     protected override void OnStartRunning()
    15.     {
    16.         EntityQuery allRoadsQuery = GetEntityQuery(
    17.             typeof(ERRoadTag),
    18.             ComponentType.ReadOnly<RoadDetails>(),
    19.             ComponentType.ReadOnly<LanePoints>());
    20.  
    21.  
    22.         roadEntities = allRoadsQuery.ToEntityArray(Allocator.Persistent);
    23.  
    24.         EntityQuery allConnectionsQuery = GetEntityQuery(
    25.             typeof(ERConnectionTag),
    26.             ComponentType.ReadOnly<ConnectionDetails>(),
    27.             ComponentType.ReadOnly<LanePoints>());
    28.  
    29.         connectionEntities = allConnectionsQuery.ToEntityArray(Allocator.Persistent);
    30.     }
    31.  
    32.     [BurstCompile]
    33.     protected override void OnUpdate()
    34.     {
    35.         System.Random random = new System.Random();
    36.         uint randomSeed = (uint)random.Next(88, 1000000);
    37.         float dt = Time.DeltaTime;
    38.         float reachedPositionDistance = 2.5f;
    39.         NativeArray<Entity> roads = roadEntities;
    40.         NativeArray<Entity> connections = connectionEntities;
    41.  
    42.         ComponentDataFromEntity<RoadDetails> RoadDetailsFromEntity = GetComponentDataFromEntity<RoadDetails>(true);
    43.         ComponentDataFromEntity<ConnectionDetails> ConnectionDetailsFromEntity = GetComponentDataFromEntity<ConnectionDetails>(true);
    44.  
    45.         BufferFromEntity<LanePoints> LanePointsFromEntity = GetBufferFromEntity<LanePoints>(true);
    46.  
    47.  
    48.         Entities.WithAll<ERAutoTag>()
    49.             .ForEach((
    50.             DynamicBuffer<AutoLanePoints> autoLanePoints,
    51.             ref AutoDetails autoDetails,
    52.             ref AutoPosition autoPosition,
    53.             ref Translation translation,
    54.             ref Rotation rotation) =>
    55.             {
    56.                 var distance = math.distance(autoPosition.Destination, translation.Value);
    57.  
    58.                 if (distance <= reachedPositionDistance)
    59.                 {
    60.                     autoPosition.CurrentPositionIndex += 1;
    61.  
    62.                     if (autoPosition.CurrentPositionIndex >= autoLanePoints.Length)
    63.                     {
    64.                         autoPosition.CurrentPositionIndex = 0;
    65.                         autoLanePoints.Clear();
    66.  
    67.                         int laneIndex = 0;
    68.                         int roadIdentity = 0;
    69.                         int connectionIdentityEnd = 0;
    70.  
    71.                         for (int i = 0; i < roads.Length; i++)
    72.                         {
    73.                             RoadDetails roadDetails = RoadDetailsFromEntity[roads[i]];
    74.  
    75.                             if ((roadDetails.RoadIdentity == autoPosition.RoadIdentity) &&
    76.                             (roadDetails.LaneIndex == autoPosition.LaneIndex) &&
    77.                             (roadDetails.ConnectionIdentityStart == autoPosition.ConnectionIdentity) &&
    78.                             (roadDetails.ConnectionIndexStart == autoPosition.ConnectionIndex)
    79.                             )
    80.                             {
    81.                                 laneIndex = roadDetails.LaneIndex;
    82.                                 roadIdentity = roadDetails.RoadIdentity;
    83.                                 connectionIdentityEnd = roadDetails.ConnectionIdentityEnd;
    84.  
    85.                                 var roadLanePointsBuffer = LanePointsFromEntity[roads[i]];
    86.                                 var roadLanePoints = roadLanePointsBuffer.ToNativeArray(Allocator.Temp);
    87.                                 var lanePointAuto = new AutoLanePoints();
    88.                                 for (int pointIndex = 0; pointIndex < roadLanePoints.Length; pointIndex++)
    89.                                 {
    90.                                     lanePointAuto.value = roadLanePoints[pointIndex].value;
    91.                                     autoLanePoints.Add(lanePointAuto);
    92.                                 }
    93.                                 break;
    94.                             }
    95.                         }
    96.  
    97.                         //Get the Connection's Lane's points
    98.                         //First find all options that have the same Idenity and Index.
    99.                         //Then we can randomly select one of the routes through the connection
    100.                         NativeList<Entity> availableConnections = new NativeList<Entity>(Allocator.Temp);
    101.  
    102.                         for (int i = 0; i < connections.Length; i++)
    103.                         {
    104.                             var connectionDetails = ConnectionDetailsFromEntity[connections[i]];
    105.  
    106.                             if ((connectionDetails.ConnectionIdentity == connectionIdentityEnd) &&
    107.                                 (connectionDetails.LaneIndexStart == laneIndex) &&
    108.                                 (connectionDetails.RoadIdentityStart == roadIdentity) &&
    109.                                 (connectionDetails.ConnectionIndexStart == autoPosition.ConnectionIndex))
    110.                             {
    111.                                 availableConnections.Add(connections[i]);
    112.                             }
    113.                         }
    114.  
    115.                         Unity.Mathematics.Random mathRandom = new Unity.Mathematics.Random(randomSeed);
    116.                         int randomValue = mathRandom.NextInt(0, availableConnections.Length);
    117.                         var connectionDetailsNew = ConnectionDetailsFromEntity[availableConnections[randomValue]];
    118.                         var connectionLanePointsBuffer = LanePointsFromEntity[availableConnections[randomValue]];
    119.                         var connectionLanePoints = connectionLanePointsBuffer.ToNativeArray(Allocator.Temp);
    120.                         var lanePoint = new AutoLanePoints();
    121.  
    122.                         for (int x = 0; x < connectionLanePoints.Length; x++)
    123.                         {
    124.                             lanePoint.value = connectionLanePoints[x].value;
    125.                             autoLanePoints.Add(lanePoint);
    126.                         }
    127.  
    128.                         //Reset the Auto's variables for the next Road/Connection selection
    129.                         autoPosition.LaneIndex = connectionDetailsNew.LaneIndexEnd;
    130.                         autoPosition.RoadIdentity = connectionDetailsNew.RoadIdentityEnd;
    131.                         autoPosition.ConnectionIdentity = connectionDetailsNew.ConnectionIdentity;
    132.                         autoPosition.ConnectionIndex = connectionDetailsNew.ConnectionIndexEnd;
    133.  
    134.                         availableConnections.Dispose();
    135.                     }
    136.  
    137.                     autoPosition.Destination = autoLanePoints[autoPosition.CurrentPositionIndex].value;
    138.                     autoPosition.Destination.y += autoDetails.yOffset;
    139.                 }
    140.  
    141.  
    142.                 float3 lookVector = autoPosition.Destination - translation.Value;
    143.                 if (!lookVector.Equals(float3.zero))
    144.                 {
    145.                     Quaternion rotationLookAt = Quaternion.LookRotation(lookVector);
    146.                     rotation.Value = rotationLookAt;
    147.                 }
    148.  
    149.                 float3 smoothedPosition = math.lerp(translation.Value, autoPosition.Destination, autoDetails.speed * dt);
    150.                 translation.Value = smoothedPosition;
    151.  
    152.             }).Schedule();
    153.     }
    154. }
     
  2. brunocoimbra

    brunocoimbra

    Joined:
    Sep 2, 2015
    Posts:
    461
    When you pass "true" in GetComponentDataFromEntity you need also to use WithReadOnly in Entities.ForEach:
    Code (CSharp):
    1. Entities.WithReadOnly(RoadDetailsFromEntity).WithReadOnly(ConnectionDetailsFromEntity).WithAll.........
    Another option is to not use GetComponentDataFromEntity at all and just use Get/Has/SetComponent directly (SystemBase codegens it to GetComponentDataFromEntity with the correct read/write access for you)
     
  3. JamesWjRose

    JamesWjRose

    Joined:
    Apr 13, 2017
    Posts:
    476
    Thank you very much, I'll check this out in the morning. You rule.

    Have a great weekend
     
    brunocoimbra likes this.
unityunity