public void Execute()
            {
                while (entityQueue.Count > 0)
                {
                    Entity entityToDestroy = entityQueue.Dequeue();

                    if (entityTransaction.Exists(entityToDestroy))
                    {
                        //Get the EntityTypeData component to figure out what type of entity we are deleting
                        EntityTypeData entityToDestroyTypeData = entityTransaction.GetSharedComponentData <EntityTypeData>(entityToDestroy);
                        switch (entityToDestroyTypeData.entityType)
                        {
                        case EntityTypeData.EntityType.Asteroid:
                        case EntityTypeData.EntityType.EnemyShip:
                        case EntityTypeData.EntityType.AllyShip:
                        case EntityTypeData.EntityType.PlayerShip:
                        {
                            //Those type of entity will require some additional logic after destruction,
                            //create the info needed and add it to the list
                            Position entityToDestroyPosition = entityTransaction.GetComponentData <Position>(entityToDestroy);
                            InfoForLogicAfterDestroy newInfo = new InfoForLogicAfterDestroy
                            {
                                entityTypeData = entityToDestroyTypeData,
                                entityPosition = entityToDestroyPosition,
                            };
                            infoForLogic.Add(newInfo);
                        }
                        break;

                        case EntityTypeData.EntityType.PlayerBolt:
                        {
                            //Player bolts are only destroyed when they collided with enemies or obstacle,
                            // add to the score in that case
                            UIData uiData = uiDataArray[0];
                            uiData.score  += scoreValue;
                            uiDataArray[0] = uiData;
                        }
                        break;
                        }
                        //This will remove the entity from the entity manager
                        entityTransaction.DestroyEntity(entityToDestroy);
                    }
                }
            }
        protected override void OnUpdate()
        {
            EntityManager.CompleteAllJobs();

            //We need to call this after EntityManager.CompleteAllJobs so that our uiEntityDataGroup is updated
            UpdateInjectedComponentGroups();

            //Copy our current UI data in a tmp array
            Entity uiEntity = uiEntityDataGroup.GetEntityArray()[0];
            UIData testData = GetComponentDataFromEntity <UIData>()[uiEntity];

            NativeArray <UIData> uiTmpDataArray = new NativeArray <UIData>(1, Allocator.TempJob);

            uiTmpDataArray[0] = testData;

            //Create a tmp list to contain the data needed to do some logic after entities destruction
            NativeList <InfoForLogicAfterDestroy> infoLogicTmpDataList = new NativeList <InfoForLogicAfterDestroy>(entityCollisionQueue.Count, Allocator.TempJob);

            //Tell the EntityManager that we will start doing entity work only via an ExclusiveEntityTransaction (that can be passed to a job)
            ExclusiveEntityTransaction exclusiveEntityTransaction = EntityManager.BeginExclusiveEntityTransaction();

            //Set up our job to destroy our entities and fill the infoLogicTmpDataList with the data we need to do some logic after the destruction
            DestroyEntityWithLogicJob destroyEntityWithLogicJob = new DestroyEntityWithLogicJob
            {
                entityTransaction = exclusiveEntityTransaction,
                uiDataArray       = uiTmpDataArray,
                entityQueue       = entityCollisionQueue,
                scoreValue        = MonoBehaviourECSBridge.Instance.destroyScoreValue,
                infoForLogic      = infoLogicTmpDataList,
            };

            JobHandle destroyHandle = destroyEntityWithLogicJob.Schedule(EntityManager.ExclusiveEntityTransactionDependency);

            EntityManager.ExclusiveEntityTransactionDependency = JobHandle.CombineDependencies(destroyHandle, EntityManager.ExclusiveEntityTransactionDependency);

            //Send the job to the worker thread queue, we need to do this because we need the job to run now
            JobHandle.ScheduleBatchedJobs();

            //Wait for it to be completed
            destroyHandle.Complete();

            //Start a new job to destroy out of bound entities
            DestroyEntityJob destroyEntityJob = new DestroyEntityJob
            {
                entityTransaction = exclusiveEntityTransaction,
                entityQueue       = entityOutOfBoundQueue,
            };

            //Make sure we depend on the previous job (only one job at a time can use the ExclusiveEntityTransaction)
            destroyHandle = destroyEntityJob.Schedule(destroyHandle);
            EntityManager.ExclusiveEntityTransactionDependency = JobHandle.CombineDependencies(destroyHandle, EntityManager.ExclusiveEntityTransactionDependency);

            //Send the job to the worker thread queue, we need to do this because we need the job to run now
            JobHandle.ScheduleBatchedJobs();

            //While the job for the entity out of bound is running, do our logic for the entity destruction on the main thread
            //The list was generated from the first job
            DestroyLogic(infoLogicTmpDataList);

            //wait for the entity out of bound destroy job to finish
            destroyHandle.Complete();

            //Tell the entity manager that we are done with the ExclusiveEntityTransaction
            EntityManager.EndExclusiveEntityTransaction();

            //We need to call this after EndExclusiveEntityTransaction so that our uiEntityDataGroup is updated
            UpdateInjectedComponentGroups();

            //Copy back the UI data with the update score
            testData = uiTmpDataArray[0];
            EntityManager.SetComponentData(uiEntity, testData);



            //dispose of our tmp array/list
            uiTmpDataArray.Dispose();
            infoLogicTmpDataList.Dispose();
        }
        protected override void OnUpdate()
        {
            if (Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.KeypadPlus))
            {
                MonoBehaviourECSBridge.Instance.amountOfBackgroundSpawner++;
            }
            else if (Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.KeypadMinus))
            {
                MonoBehaviourECSBridge.Instance.amountOfBackgroundSpawner--;
            }
            MonoBehaviourECSBridge.Instance.amountOfBackgroundSpawner = math.max(0, MonoBehaviourECSBridge.Instance.amountOfBackgroundSpawner);

            //Create or destroy background spawners
            //This should only happen on the first frame and any frame we change the background spawner count
            if (backGroundSpawnerNativeList.Length < MonoBehaviourECSBridge.Instance.amountOfBackgroundSpawner)
            {
                while (backGroundSpawnerNativeList.Length != MonoBehaviourECSBridge.Instance.amountOfBackgroundSpawner)
                {
                    backGroundSpawnerNativeList.Add(CreateBackgroundSpawner(backGroundSpawnerNativeList.Length));
                }
            }
            else if (backGroundSpawnerNativeList.Length > MonoBehaviourECSBridge.Instance.amountOfBackgroundSpawner)
            {
                while (backGroundSpawnerNativeList.Length != MonoBehaviourECSBridge.Instance.amountOfBackgroundSpawner)
                {
                    Entity backgroundSpawnerToRemove = backGroundSpawnerNativeList[backGroundSpawnerNativeList.Length - 1];
                    backGroundSpawnerNativeList.RemoveAtSwapBack(backGroundSpawnerNativeList.Length - 1);
                    EntityManager.DestroyEntity(backgroundSpawnerToRemove);
                }
            }

            //If we deleted or created entities we will need to update our injected component group
            UpdateInjectedComponentGroups();

            //gameplay logic
            if (playerGroup.Length == 0)
            {
                if (!gameOver)
                {
                    gameOver          = true;
                    timeSinceGameOver = 0.0f;
                    if (EntityManager.Exists(gameplaySpawnerEntity))
                    {
                        EntityManager.DestroyEntity(gameplaySpawnerEntity);
                    }
                }
                else if (!restart)
                {
                    timeSinceGameOver += Time.deltaTime;
                    if (timeSinceGameOver > 2.0f)
                    {
                        restart = true;
                    }
                }

                if (restart)
                {
                    if (Input.GetKeyDown(KeyCode.R))
                    {
                        RestartGame();
                    }
                }
            }
            else
            {
                MonoBehaviourECSBridge.Instance.playerPosition = playerGroup.playerMoveData[0].position;
            }

            //If we deleted or created entities we will need to update our injected component group
            UpdateInjectedComponentGroups();

            UIData tmpUIData = uiDataGroup.uiEntityData[0];

            tmpUIData.gameOver          = gameOver ? 1 : 0;
            tmpUIData.restart           = restart ? 1 : 0;
            uiDataGroup.uiEntityData[0] = tmpUIData;
        }