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; }