Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question InvalidOperationException: The previously scheduled job LocalToWorldSystem

Discussion in 'Entity Component System' started by T3M4CH, Jan 24, 2023.

  1. T3M4CH

    T3M4CH

    Joined:
    Aug 29, 2019
    Posts:
    5
    Error Message :
    Code (CSharp):
    1. InvalidOperationException: The previously scheduled job LocalToWorldSystem:ComputeChildLocalToWorldJob reads from the ComponentTypeHandle<Unity.Collections.NativeText.ReadOnly> ComputeChildLocalToWorldJob.JobData.LocalTransformLookupRO. You are trying to schedule a new job SpawnZombieJob, which writes to the same ComponentTypeHandle<Unity.Collections.NativeText.ReadOnly> (via SpawnZombieJob.JobData.__Core_Scripts_ZombiesExample_ComponentsAndTags_GraveyardAspectTypeHandle._transformAspect.m_LocalTransformCth). To guarantee safety, you must include LocalToWorldSystem:ComputeChildLocalToWorldJob as a dependency of the newly scheduled job.
    I've got an error when I'm injecting GraveyardAspect

    Code (CSharp):
    1.  [BurstCompile]
    2.     public partial struct SpawnZombieJob : IJobEntity
    3.     {
    4.         public float DeltaTime;
    5.         public EntityCommandBuffer Ecb;
    6.  
    7.         private void Execute(GraveyardAspect graveyard)
    8.         {
    9.             graveyard.ZombieSpawnTimer -= DeltaTime;
    10.             if (!graveyard.TimeToSpawnZombie) return;
    11.            
    12.             graveyard.ZombieSpawnTimer = graveyard.ZombieSpawnRate;
    13.             var newZombie = Ecb.Instantiate(graveyard.ZombiePrefab);
    14.         }
    15.     }
    So there's GraveyardAspect Script :

    Code (CSharp):
    1. public readonly partial struct GraveyardAspect : IAspect
    2.     {
    3.         private const float BrainSafetyRadiusSq = 15;
    4.  
    5.         public readonly Entity Entity;
    6.  
    7.         private readonly TransformAspect _transformAspect;
    8.  
    9.         private readonly RefRO<GraveyardProperties> _graveyardProperties;
    10.         private readonly RefRW<GraveyardRandom> _graveyardRandom;
    11.         private readonly RefRW<ZombieSpawnPoints> _zombieSpawnPoints;
    12.         private readonly RefRW<ZombieSpawnTimer> _zombieSpawnTimer;
    13.  
    14.         public NativeArray<float3> ZombieSpawnPoints
    15.         {
    16.             get => _zombieSpawnPoints.ValueRO.Value;
    17.             set => _zombieSpawnPoints.ValueRW.Value = value;
    18.         }
    19.  
    20.         public LocalTransform GetRandomTombstoneTransform()
    21.         {
    22.             return new LocalTransform
    23.             {
    24.                 Position = GetRandomPosition(),
    25.                 Rotation = GetRandomRotation(),
    26.                 Scale = GetRandomScale(0.5f),
    27.             };
    28.         }
    29.  
    30.         private float3 GetRandomPosition()
    31.         {
    32.             float3 randomPosition;
    33.  
    34.             do
    35.             {
    36.                 randomPosition = _graveyardRandom.ValueRW.Value.NextFloat3(MinCorner, MaxCorner);
    37.             } while (math.distancesq(_transformAspect.WorldPosition, randomPosition) <=
    38.                      BrainSafetyRadiusSq * BrainSafetyRadiusSq);
    39.  
    40.             return randomPosition;
    41.         }
    42.  
    43.         private float3 MinCorner => _transformAspect.WorldPosition - HalfDimensions;
    44.         private float3 MaxCorner => _transformAspect.WorldPosition + HalfDimensions;
    45.  
    46.         private float3 HalfDimensions => new()
    47.         {
    48.             x = _graveyardProperties.ValueRO.FieldDimensions.x * .5f,
    49.             y = 0,
    50.             z = _graveyardProperties.ValueRO.FieldDimensions.y * .5f
    51.         };
    52.  
    53.         public int NumberTombstonesToSpawn => _graveyardProperties.ValueRO.NumberTombstonesToSpawn;
    54.         public Entity TombstonePrefab => _graveyardProperties.ValueRO.TombstonePrefab;
    55.  
    56.         private quaternion GetRandomRotation() =>
    57.             quaternion.RotateY(_graveyardRandom.ValueRW.Value.NextFloat(-0.25f, 0.25f));
    58.  
    59.         private float GetRandomScale(float min) => _graveyardRandom.ValueRW.Value.NextFloat(min, 1);
    60.  
    61.         public float ZombieSpawnTimer
    62.         {
    63.             get => _zombieSpawnTimer.ValueRO.Value;
    64.             set => _zombieSpawnTimer.ValueRW.Value = value;
    65.         }
    66.  
    67.         public bool TimeToSpawnZombie => ZombieSpawnTimer <= 0f;
    68.  
    69.         public float ZombieSpawnRate => _graveyardProperties.ValueRO.ZombieSpawnRate;
    70.  
    71.         public Entity ZombiePrefab => _graveyardProperties.ValueRO.ZombiePrefab;
    72.     }
    And system where's injecting

    Code (CSharp):
    1.  [BurstCompile]
    2.     public partial struct SpawnZombieSystem : ISystem
    3.     {
    4.         [BurstCompile]
    5.         public void OnCreate(ref SystemState state)
    6.         {
    7.         }
    8.  
    9.         [BurstCompile]
    10.         public void OnDestroy(ref SystemState state)
    11.         {
    12.         }
    13.  
    14.         [BurstCompile]
    15.         public void OnUpdate(ref SystemState state)
    16.         {
    17.             var deltaTime = SystemAPI.Time.DeltaTime;
    18.             var ecbSingleton = SystemAPI.GetSingleton<BeginInitializationEntityCommandBufferSystem.Singleton>()
    19.                 .CreateCommandBuffer(state.WorldUnmanaged);
    20.  
    21.             new SpawnZombieJob
    22.             {
    23.                 DeltaTime = deltaTime,
    24.                 Ecb = ecbSingleton
    25.             }.Run();
    26.         }
    27.     }
    28.  
    29.     [BurstCompile]
    30.     public partial struct SpawnZombieJob : IJobEntity
    31.     {
    32.         public float DeltaTime;
    33.         public EntityCommandBuffer Ecb;
    34.  
    35.         private void Execute(GraveyardAspect graveyard)
    36.         {
    37.             graveyard.ZombieSpawnTimer -= DeltaTime;
    38.             if (!graveyard.TimeToSpawnZombie) return;
    39.            
    40.             graveyard.ZombieSpawnTimer = graveyard.ZombieSpawnRate;
    41.             var newZombie = Ecb.Instantiate(graveyard.ZombiePrefab);
    42.         }
    43.     }
    H
     
  2. T3M4CH

    T3M4CH

    Joined:
    Aug 29, 2019
    Posts:
    5
    I change this

    Code (CSharp):
    1.  new SpawnZombieJob
    2.             {
    3.                 DeltaTime = deltaTime,
    4.                 Ecb = ecbSingleton
    5.             }.Run();
    to this

    Code (CSharp):
    1.  new SpawnZombieJob
    2.             {
    3.                 DeltaTime = deltaTime,
    4.                 Ecb = ecbSingleton
    5.             }.Schedule();
    And now it works.. Could somebody explain what's going here?
     
    ageana and iamfarcry4 like this.
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,223
    state.Dependency was not completed when you called Run(). But it doesn't need to be completed when you call Schedule() because it is treated as a job input dependency. To make it work with Run(), you would need to call state.CompleteDependency() before calling Run().
     
    ageana and T3M4CH like this.