Upgrading preview 6 0.10.0 Issues

I had functionality to restart my game using IJobForEachWithEntity. Now that this interface is obsolete, I want to clean up my systems. However, every time I try to destroy all the entities, I get the following error:

InvalidOperationException: The previously scheduled job RestartGameSystem:<>c__DisplayClass_OnUpdate_LambdaJob3 writes to the NativeArray <>c__DisplayClass_OnUpdate_LambdaJob3.JobData._lambdaParameterValueProviders.forParameter_translation._type. You are trying to schedule a new job RestartGameSystem:<>c__DisplayClass_OnUpdate_LambdaJob4, which writes to the same NativeArray (via <>c__DisplayClass_OnUpdate_LambdaJob4.JobData._lambdaParameterValueProviders.forParameter_translation._type). To guarantee safety, you must include Restart
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.10.0-preview.6/Unity.Entities/IJobChunk.cs:216)
Unity.Entities.JobChunkExtensions.ScheduleParallel[T] (T jobData, Unity.Entities.EntityQuery query, Unity.Jobs.JobHandle dependsOn) (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/IJobChunk.cs:128)
Source.Runtime.Game.GameLogic.RestartGameSystem.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at Assets/Source/Runtime/Game/GameLogic/System/RestartGameSystem.cs:63)
Unity.Entities.JobComponentSystem.Update () (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/JobComponentSystem.cs:141)
Unity.Entities.ComponentSystemGroup.UpdateAllSystems () (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:240)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/Stubs/Unity/Debug.cs:19)
Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:244)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:219)
Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystem.cs:109)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ScriptBehaviourUpdateOrder.cs:196)

Here is my code:

        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var handle = inputDeps;
            var playerDataArray = GetComponentDataFromEntity<PlayerData>();
            var playerData = playerDataArray[PlayerDataEntity];

            if (playerData.restart == 1) {
                playerData.restart = 0;
                playerData.gameOver = 0;
                playerData.score = 0;
                playerData.lives = Utils.MaxLives;
                playerDataArray[PlayerDataEntity] = playerData;

                var entityBuffer = _entityCommandBufferSystem.CreateCommandBuffer().ToConcurrent();
                var removeBuffer = _entityCommandBufferSystem.CreateCommandBuffer().ToConcurrent();

                var ballHandle = Entities.ForEach((Entity entity, ref BallData data, ref Translation translation, ref PhysicsVelocity velocity) => {
                    translation.Value = data.initialPosition;
                    velocity.Linear = data.initialVelocity;
                }).Schedule(inputDeps);

                var paddleHandle = Entities.ForEach((Entity entity, ref PaddleData paddle, ref Translation translation) => {
                    translation.Value = paddle.initialPosition;
                }).Schedule(ballHandle);

                var layoutData = BrickLayout;
                var resetBrickHandle = Entities.ForEach((Entity entity, int entityInQueryIndex, ref GameBoardData data, ref WorldRenderBounds world) => {
                    entityBuffer.AddComponent(entityInQueryIndex, entity, layoutData);
                }).Schedule(paddleHandle);

                var resetSlowHandle = Entities.ForEach((Entity entity, int entityInQueryIndex, ref PhysicsVelocity velocity, ref Translation translation) => {
                    entityBuffer.RemoveComponent<PhysicsVelocityScale>(entityInQueryIndex, entity);
                }).Schedule(resetBrickHandle);

                var destroyHandle = Entities.ForEach((Entity entity, int entityInQueryIndex, ref Translation translation, in PaddleData paddle) => {
                    removeBuffer.DestroyEntity(entityInQueryIndex, entity);
                }).Schedule(inputDeps);

                _entityCommandBufferSystem.AddJobHandleForProducer(ballHandle);
                _entityCommandBufferSystem.AddJobHandleForProducer(destroyHandle);

                handle = JobHandle.CombineDependencies(ballHandle, destroyHandle);
            }

            return handle;
        }

Any one have any ideas? Furthermore, as I reset my PlayerData. Is this the best way?

I think you missed to use the resetSlowHandle instead of the ballHandle in the end:

_entityCommandBufferSystem.AddJobHandleForProducer(resetSlowHandle);
_entityCommandBufferSystem.AddJobHandleForProducer(destroyHandle);

handle = JobHandle.CombineDependencies(resetSlowHandle, destroyHandle);

Oh yea, you’re right about that. I still have another error now:

InvalidOperationException: The previously scheduled job RestartGameSystem:<>c__DisplayClass_OnUpdate_LambdaJob3 writes to the NativeArray <>c__DisplayClass_OnUpdate_LambdaJob3.JobData._lambdaParameterValueProviders.forParameter_translation._type. You are trying to schedule a new job RestartGameSystem:<>c__DisplayClass_OnUpdate_LambdaJob4, which writes to the same NativeArray (via <>c__DisplayClass_OnUpdate_LambdaJob4.JobData._lambdaParameterValueProviders.forParameter_translation._type). To guarantee safety, you must include Restart
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.10.0-preview.6/Unity.Entities/IJobChunk.cs:216)
Unity.Entities.JobChunkExtensions.ScheduleParallel[T] (T jobData, Unity.Entities.EntityQuery query, Unity.Jobs.JobHandle dependsOn) (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/IJobChunk.cs:128)
Source.Runtime.Game.GameLogic.RestartGameSystem.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at Assets/Source/Runtime/Game/GameLogic/System/RestartGameSystem.cs:63)
Unity.Entities.JobComponentSystem.Update () (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/JobComponentSystem.cs:141)
Unity.Entities.ComponentSystemGroup.UpdateAllSystems () (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:240)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/Stubs/Unity/Debug.cs:19)
Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:244)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:219)
Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystem.cs:109)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ScriptBehaviourUpdateOrder.cs:196)

Hmm, looking further into the error it seems to be complaining to the write access to Translation in the last query without including the others write access as dependency to it.

var destroyHandle = Entities.ForEach((Entity entity, int entityInQueryIndex, ref Translation translation, in PaddleData paddle) => {
    removeBuffer.DestroyEntity(entityInQueryIndex, entity);
}).Schedule(paddleHandle); //instead of inputDeps

This should fix that.

Oh, just noticed that the resetSlowHandle = … also access the Translation component, probably you will need to run all those sequentially.

Thanks @brunocoimbra . I realized that I did a copy and paste fail. Thankfully I just diff’d the file.

                var destroyHandle = Entities.ForEach((Entity entity, int entityInQueryIndex, in BrickData brick) => {
                    removeBuffer.DestroyEntity(entityInQueryIndex, entity);
                }).Schedule(inputDeps);
1 Like