protected override JobHandle OnUpdate(JobHandle inputDeps) { EntityArray boltSpawnerEntityDataArray = boltSpawnerEntityDataGroup.GetEntityArray(); if (boltSpawnerEntityDataArray.Length == 0) { return(inputDeps); } BoltSpawnerEntityData boltSpawnerEntityData = GetComponentDataFromEntity <BoltSpawnerEntityData>()[boltSpawnerEntityDataArray[0]]; uniqueEntityTypes.Clear(); EntityManager.GetAllUniqueSharedComponentData(uniqueEntityTypes); JobHandle spawnJobHandle = new JobHandle(); JobHandle spawnJobDependency = inputDeps; for (int i = 0; i != uniqueEntityTypes.Count; i++) { EntityTypeData entityTypeData = uniqueEntityTypes[i]; if (entityTypeData.entityType == EntityTypeData.EntityType.EnemyShip || entityTypeData.entityType == EntityTypeData.EntityType.AllyShip) { aiSpawnBoltDataGroup.SetFilter(uniqueEntityTypes[i]); NativeQueue <Entity> .Concurrent spawnBoltEntityQueueToUse = boltSpawnerEntityData.enemyBoltSpawnQueueConcurrent; if (entityTypeData.entityType == EntityTypeData.EntityType.AllyShip) { spawnBoltEntityQueueToUse = boltSpawnerEntityData.allyBoltSpawnQueueConcurrent; } AISpawnBoltJob aiSpawnBoltJob = new AISpawnBoltJob { entityArray = aiSpawnBoltDataGroup.GetEntityArray(), aiPositionArray = aiSpawnBoltDataGroup.GetComponentDataArray <Position>(), aiRotationArray = aiSpawnBoltDataGroup.GetComponentDataArray <Rotation>(), aiSpawnBoltDataArray = aiSpawnBoltDataGroup.GetComponentDataArray <AISpawnBoltData>(), spawnBoltEntityQueue = spawnBoltEntityQueueToUse, deltaTime = Time.deltaTime }; JobHandle tmpJobHandle = aiSpawnBoltJob.Schedule(aiSpawnBoltJob.aiSpawnBoltDataArray.Length, MonoBehaviourECSBridge.Instance.GetJobBatchCount(aiSpawnBoltJob.aiSpawnBoltDataArray.Length), spawnJobDependency); spawnJobHandle = JobHandle.CombineDependencies(spawnJobHandle, tmpJobHandle); spawnJobDependency = JobHandle.CombineDependencies(spawnJobDependency, tmpJobHandle); } } aiSpawnBoltDataGroup.ResetFilter(); return(spawnJobHandle); }
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 EntityInstanceRenderData entityToDestroyRenderData = entityTransaction.GetComponentData <EntityInstanceRenderData>(entityToDestroy); InfoForLogicAfterDestroy newInfo = new InfoForLogicAfterDestroy { entityTypeData = entityToDestroyTypeData, renderData = entityToDestroyRenderData, }; infoForLogic.Add(newInfo); } break; case EntityTypeData.EntityType.Bolt: { //Player bolts are only destroyed when they collided with enemies or obstacle, // add to the score in that case BoltTypeData boltTypeData = entityTransaction.GetSharedComponentData <BoltTypeData>(entityToDestroy); if (boltTypeData.boltType == BoltTypeData.BoltType.PlayerBolt) { 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 JobHandle OnUpdate(JobHandle inputDeps) { UnityEngine.Profiling.Profiler.BeginSample("System Init"); currentCellDictionary++; if (currentCellDictionary >= cellEntityTypeDictionaryArray.Length) { currentCellDictionary = 0; } //Make sure we cleared all the hash maps allClearCellsJobHandle.Complete(); uniqueEntityTypes.Clear(); EntityManager.GetAllUniqueSharedComponentDatas(uniqueEntityTypes); entityTypeList.Clear(); subsetEntityDictionary.Clear(); subsetMinMaxDataDictionary.Clear(); fillCellJobHandleDictionary.Clear(); JobHandle allBoundGroupDependencies = boundDataGroup.GetDependency(); UnityEngine.Profiling.Profiler.EndSample(); UnityEngine.Profiling.Profiler.BeginSample("FillJobSetup"); JobHandle allocateCellJobDependency = allClearCellsJobHandle; JobHandle allocateCellJobHandle = new JobHandle(); EntityArray[] subsetEntityArrayArray = new EntityArray[uniqueEntityTypes.Count]; ComponentDataArray <EntityBoundMinMaxData>[] subsetMinMaxDataArrayArray = new ComponentDataArray <EntityBoundMinMaxData> [uniqueEntityTypes.Count]; //create the hashMaps if needed and get the subset arrays we will use UnityEngine.Profiling.Profiler.BeginSample("GetEntityArray"); for (int i = 0; i != uniqueEntityTypes.Count; i++) { EntityTypeData entityTypeData = uniqueEntityTypes[i]; boundDataGroup.SetFilter(entityTypeData); subsetEntityArrayArray[i] = boundDataGroup.GetEntityArray(); subsetMinMaxDataArrayArray[i] = boundDataGroup.GetComponentDataArray <EntityBoundMinMaxData>(); if (subsetEntityArrayArray[i].Length != 0) { CreateCellHashMap(uniqueEntityTypes[i].entityType); } } UnityEngine.Profiling.Profiler.EndSample(); //set the cells capacity now UnityEngine.Profiling.Profiler.BeginSample("Resize Hash Map"); for (int i = 0; i != uniqueEntityTypes.Count; i++) { EntityTypeData entityTypeData = uniqueEntityTypes[i]; EntityArray subsetEntityArray = subsetEntityArrayArray[i]; if (subsetEntityArray.Length == 0) { continue; } NativeMultiHashMap <int, HashMapData> tmpOutputCell = cellEntityTypeDictionary[entityTypeData.entityType]; //TODO: Test the memory usage //We are setting the capacity really high to not run out of space while running our jobs if (tmpOutputCell.Capacity < subsetEntityArray.Length * 10) { AllocateCellsJob allocateCellJob = new AllocateCellsJob { outputCells = tmpOutputCell, capacityWanted = subsetEntityArray.Length * 20, }; allocateCellJobHandle = JobHandle.CombineDependencies(allocateCellJob.Schedule(allocateCellJobDependency), allocateCellJobHandle); } } UnityEngine.Profiling.Profiler.EndSample(); allocateCellJobHandle.Complete(); JobHandle fillCellJobDependency = JobHandle.CombineDependencies(inputDeps, allBoundGroupDependencies); for (int i = 0; i != uniqueEntityTypes.Count; i++) { EntityTypeData entityTypeData = uniqueEntityTypes[i]; EntityArray subsetEntityArray = subsetEntityArrayArray[i]; ComponentDataArray <EntityBoundMinMaxData> subsetMinMaxDataArray = subsetMinMaxDataArrayArray[i]; if (subsetEntityArray.Length == 0) { continue; } NativeMultiHashMap <int, HashMapData> .Concurrent tmpOutputCell = cellEntityTypeDictionary[entityTypeData.entityType]; float3 tmpOutputCellSize = cellSizeEntityDictionary[entityTypeData.entityType]; UnityEngine.Profiling.Profiler.BeginSample("Allocate tmp Array"); NativeArray <Entity> subsetEntityArrayOutput = new NativeArray <Entity>(subsetEntityArray.Length, Allocator.TempJob); NativeArray <EntityBoundMinMaxData> subsetMinMaxDataArrayOutput = new NativeArray <EntityBoundMinMaxData>(subsetEntityArray.Length, Allocator.TempJob); UnityEngine.Profiling.Profiler.EndSample(); FillCellJob fillCellJob = new FillCellJob { entityArray = subsetEntityArray, entityBoundMinMaxDataArray = subsetMinMaxDataArray, entityArrayOutput = subsetEntityArrayOutput, entityBoundMinMaxDataArrayOutput = subsetMinMaxDataArrayOutput, outputCells = tmpOutputCell, cellSizes = tmpOutputCellSize, }; JobHandle previousFillJobDependency; boundDataGroup.SetFilter(entityTypeData); JobHandle jobDependency = JobHandle.CombineDependencies(fillCellJobDependency, boundDataGroup.GetDependency()); if (fillCellJobHandleDictionary.TryGetValue(entityTypeData.entityType, out previousFillJobDependency)) { jobDependency = JobHandle.CombineDependencies(jobDependency, previousFillJobDependency); } JobHandle fillCellJobHandle = fillCellJob.Schedule(subsetEntityArray.Length, MonoBehaviourECSBridge.Instance.GetJobBatchCount(subsetEntityArray.Length), jobDependency); entityTypeList.Add(entityTypeData.entityType); subsetEntityDictionary.Add(entityTypeData.entityType, subsetEntityArrayOutput); subsetMinMaxDataDictionary.Add(entityTypeData.entityType, subsetMinMaxDataArrayOutput); fillCellJobHandleDictionary.Add(entityTypeData.entityType, fillCellJobHandle); } UnityEngine.Profiling.Profiler.EndSample(); if (fillCellJobHandleDictionary.Count == 0) { return(inputDeps); } //JobHandle.ScheduleBatchedJobs(); UnityEngine.Profiling.Profiler.BeginSample("CollisionJobSetup"); JobHandle previousCollisionJobHandle = new JobHandle(); previousCollisionJobHandle = scheduleCollisionJob(EntityTypeData.EntityType.Asteroid, EntityTypeData.EntityType.Bolt, previousCollisionJobHandle); previousCollisionJobHandle = scheduleCollisionJob(EntityTypeData.EntityType.Asteroid, EntityTypeData.EntityType.EnemyShip, previousCollisionJobHandle); previousCollisionJobHandle = scheduleCollisionJob(EntityTypeData.EntityType.Asteroid, EntityTypeData.EntityType.AllyShip, previousCollisionJobHandle); previousCollisionJobHandle = scheduleCollisionJob(EntityTypeData.EntityType.EnemyShip, EntityTypeData.EntityType.Bolt, previousCollisionJobHandle); previousCollisionJobHandle = scheduleCollisionJob(EntityTypeData.EntityType.EnemyShip, EntityTypeData.EntityType.AllyShip, previousCollisionJobHandle); previousCollisionJobHandle = scheduleCollisionJob(EntityTypeData.EntityType.AllyShip, EntityTypeData.EntityType.Bolt, previousCollisionJobHandle); previousCollisionJobHandle = scheduleCollisionJob(EntityTypeData.EntityType.PlayerShip, EntityTypeData.EntityType.Asteroid, previousCollisionJobHandle); previousCollisionJobHandle = scheduleCollisionJob(EntityTypeData.EntityType.PlayerShip, EntityTypeData.EntityType.Bolt, previousCollisionJobHandle); previousCollisionJobHandle = scheduleCollisionJob(EntityTypeData.EntityType.PlayerShip, EntityTypeData.EntityType.EnemyShip, previousCollisionJobHandle); UnityEngine.Profiling.Profiler.EndSample(); JobHandle.ScheduleBatchedJobs(); UnityEngine.Profiling.Profiler.BeginSample("DisposeJobSetup"); JobHandle jobHandleToReturn = new JobHandle(); List <JobHandle> clearCellJobHandleList = new List <JobHandle>(entityTypeList.Count); for (int i = 0; i < entityTypeList.Count; i++) { if (subsetEntityDictionary.ContainsKey(entityTypeList[i])) { jobHandleToReturn = JobHandle.CombineDependencies(fillCellJobHandleDictionary[entityTypeList[i]], jobHandleToReturn); ClearCellsJob clearCellsJob = new ClearCellsJob { entityArray = subsetEntityDictionary[entityTypeList[i]], entityBoundMinMaxDataArray = subsetMinMaxDataDictionary[entityTypeList[i]], outputCells = cellEntityTypeDictionary[entityTypeList[i]], }; JobHandle clearCellsJobHandle = clearCellsJob.Schedule(JobHandle.CombineDependencies(fillCellJobHandleDictionary[entityTypeList[i]], previousCollisionJobHandle)); clearCellJobHandleList.Add(clearCellsJobHandle); } } jobHandleToReturn = JobHandle.CombineDependencies(previousCollisionJobHandle, jobHandleToReturn); UnityEngine.Profiling.Profiler.EndSample(); NativeArray <JobHandle> clearCellsJobHandleArray = new NativeArray <JobHandle>(clearCellJobHandleList.ToArray(), Allocator.Temp); allClearCellsJobHandle = JobHandle.CombineDependencies(clearCellsJobHandleArray); clearCellsJobHandleArray.Dispose(); return(jobHandleToReturn); }
protected override void OnUpdate() { //Go over all our spawners and figure out if any new entity need to be spawned //Add the spawning info to spawnerSpawnInfoList for (int i = 0; i < spawnerDataGroup.Length; i++) { SpawnerPositionData spawnerPositionData = spawnerDataGroup.spawnerPositionDataArray[i]; SpawnerHazardData spawnerHazardData = spawnerDataGroup.spawnerHazardDataArray[i]; SpawnerSpawnData spawnerSpawnData = spawnerDataGroup.spawnerSpawnDataArray[i]; if (spawnerHazardData.hazardIndexArrayLength == 0) { continue; } spawnerSpawnData.timeSinceLastSpawn += Time.deltaTime; while (spawnerSpawnData.timeSinceLastSpawn >= spawnerSpawnData.spawnDelay) { spawnerSpawnData.timeSinceLastSpawn -= spawnerSpawnData.spawnDelay; float yPositionSpawn = spawnerPositionData.position.y; //Get a random index to spawn, the range depend on the amount of hazards we set in the editor int hazardToSpawnIndex = Random.Range(0, spawnerHazardData.hazardIndexArrayLength); SpawnerSpawnInfo spawnInfo = new SpawnerSpawnInfo { spawnYPosition = yPositionSpawn, hazardIndexToSpawn = hazardToSpawnIndex, isBackgroundSpawn = spawnerHazardData.isBackgroundSpawner, }; spawnerSpawnInfoList.Add(spawnInfo); } spawnerDataGroup.spawnerSpawnDataArray[i] = spawnerSpawnData; } float3 cameraPosition = MonoBehaviourECSBridge.Instance.gameCamera.transform.position; float3 forwardDirection = new float3(0.0f, 0.0f, 1.0f); //We use the view frustum height/witdh at our spawner y position to figure out where to spawn the new entities //The calculation assume a camera pointing down (no angle) for (int i = 0; i < spawnerSpawnInfoList.Length; i++) { SpawnerSpawnInfo spawnInfo = spawnerSpawnInfoList[i]; float yPosition = spawnInfo.spawnYPosition; float ydeltaFromCamera = Mathf.Abs(yPosition - cameraPosition.y); float halfFrustumHeight = ydeltaFromCamera * Mathf.Tan(Camera.main.fieldOfView * 0.5f * Mathf.Deg2Rad); //Spawn outside of the view frustrum to avoid any "popup" halfFrustumHeight *= 1.05f; float halfFrustumWidth = halfFrustumHeight * MonoBehaviourECSBridge.Instance.gameCamera.aspect; //Enemy/Hazard are spawned from the top of the screen, Allies are spawned from the bottom float3 spawnPositionHazard = new Vector3(Random.Range(cameraPosition.x - halfFrustumWidth, cameraPosition.x + halfFrustumWidth), yPosition, cameraPosition.z + halfFrustumHeight); float3 spawnPositionAlly = new Vector3(Random.Range(cameraPosition.x - halfFrustumWidth, cameraPosition.x + halfFrustumWidth), yPosition, cameraPosition.z - halfFrustumHeight); //Spawn the hazard using the index we randomnly generated Entity newHazardEntity = EntityManager.Instantiate(MonoBehaviourECSBridge.Instance.GetPrefabHazardEntity(spawnInfo.hazardIndexToSpawn, spawnInfo.isBackgroundSpawn)); //Make sure to remove the prefab "tag" data component EntityManager.RemoveComponent <EntityPrefabData>(newHazardEntity); //Based on the type of entity spawned, set the data needed for it EntityTypeData entityTypeData = EntityManager.GetSharedComponentData <EntityTypeData>(newHazardEntity); switch (entityTypeData.entityType) { case EntityTypeData.EntityType.Asteroid: { Vector3 spawnRenderForward = new Vector3(Random.value, Random.value, 1.0f); spawnRenderForward.Normalize(); Vector3 spawnRotationAxis = new Vector3(Random.value, 1.0f, Random.value); spawnRotationAxis.Normalize(); AsteroidMoveData moveData = EntityManager.GetComponentData <AsteroidMoveData>(newHazardEntity); moveData.position = spawnPositionHazard; moveData.forwardDirection = -forwardDirection; moveData.renderForward = spawnRenderForward; moveData.rotationAxis = spawnRotationAxis; EntityManager.SetComponentData <AsteroidMoveData>(newHazardEntity, moveData); } break; case EntityTypeData.EntityType.EnemyShip: { AIMoveData moveData = EntityManager.GetComponentData <AIMoveData>(newHazardEntity); moveData.position = spawnPositionHazard; moveData.forwardDirection = -forwardDirection; EntityManager.SetComponentData <AIMoveData>(newHazardEntity, moveData); } break; case EntityTypeData.EntityType.AllyShip: { AIMoveData moveData = EntityManager.GetComponentData <AIMoveData>(newHazardEntity); moveData.position = spawnPositionAlly; moveData.forwardDirection = forwardDirection; EntityManager.SetComponentData <AIMoveData>(newHazardEntity, moveData); } break; } } spawnerSpawnInfoList.Clear(); }
protected override void OnUpdate() { ArchetypeChunkComponentType <SpawnerPositionData> spawnerPositionDataRO = GetArchetypeChunkComponentType <SpawnerPositionData>(true); ArchetypeChunkComponentType <SpawnerHazardData> spawnerHazardDataRO = GetArchetypeChunkComponentType <SpawnerHazardData>(true); ArchetypeChunkComponentType <SpawnerSpawnData> spawnerSpawnDataRW = GetArchetypeChunkComponentType <SpawnerSpawnData>(false); NativeArray <ArchetypeChunk> spawnerDataChunkArray = spawnerDataGroup.CreateArchetypeChunkArray(Allocator.TempJob); if (spawnerDataChunkArray.Length == 0) { spawnerDataChunkArray.Dispose(); return; } //Go over all our spawners and figure out if any new entity need to be spawned //Add the spawning info to spawnerSpawnInfoList for (int chunkIndex = 0; chunkIndex < spawnerDataChunkArray.Length; chunkIndex++) { ArchetypeChunk chunk = spawnerDataChunkArray[chunkIndex]; int dataCount = chunk.Count; NativeArray <SpawnerPositionData> spawnerPositionDataArray = chunk.GetNativeArray(spawnerPositionDataRO); NativeArray <SpawnerHazardData> spawnerHazardDataArray = chunk.GetNativeArray(spawnerHazardDataRO); NativeArray <SpawnerSpawnData> spawnerSpawnDataArray = chunk.GetNativeArray(spawnerSpawnDataRW); for (int dataIndex = 0; dataIndex < dataCount; dataIndex++) { SpawnerPositionData spawnerPositionData = spawnerPositionDataArray[dataIndex]; SpawnerHazardData spawnerHazardData = spawnerHazardDataArray[dataIndex]; SpawnerSpawnData spawnerSpawnData = spawnerSpawnDataArray[dataIndex]; if (spawnerHazardData.hazardIndexArrayLength == 0) { continue; } spawnerSpawnData.timeSinceLastSpawn += Time.deltaTime; while (spawnerSpawnData.timeSinceLastSpawn >= spawnerSpawnData.spawnDelay) { spawnerSpawnData.timeSinceLastSpawn -= spawnerSpawnData.spawnDelay; float yPositionSpawn = spawnerPositionData.position.y; //Get a random index to spawn, the range depend on the amount of hazards we set in the editor int hazardToSpawnIndex = randomGenerator.NextInt(0, spawnerHazardData.hazardIndexArrayLength); SpawnerSpawnInfo spawnInfo = new SpawnerSpawnInfo { spawnYPosition = yPositionSpawn, hazardIndexToSpawn = hazardToSpawnIndex, isBackgroundSpawn = spawnerHazardData.isBackgroundSpawner, }; spawnerSpawnInfoList.Add(spawnInfo); } spawnerSpawnDataArray[dataIndex] = spawnerSpawnData; } } spawnerDataChunkArray.Dispose(); float3 cameraPosition = MonoBehaviourECSBridge.Instance.gameCamera.transform.position; float3 forwardDirection = new float3(0.0f, 0.0f, 1.0f); //We use the view frustum height/witdh at our spawner y position to figure out where to spawn the new entities //The calculation assume a camera pointing down (no angle) for (int i = 0; i < spawnerSpawnInfoList.Length; i++) { SpawnerSpawnInfo spawnInfo = spawnerSpawnInfoList[i]; float yPosition = spawnInfo.spawnYPosition; float ydeltaFromCamera = Mathf.Abs(yPosition - cameraPosition.y); float halfFrustumHeight = ydeltaFromCamera * Mathf.Tan(Camera.main.fieldOfView * 0.5f * Mathf.Deg2Rad); //Spawn outside of the view frustrum to avoid any "popup" halfFrustumHeight *= 1.05f; float halfFrustumWidth = halfFrustumHeight * MonoBehaviourECSBridge.Instance.gameCamera.aspect; //Enemy/Hazard are spawned from the top of the screen, Allies are spawned from the bottom float3 spawnPositionHazard = new Vector3(randomGenerator.NextFloat(cameraPosition.x - halfFrustumWidth, cameraPosition.x + halfFrustumWidth), yPosition, cameraPosition.z + halfFrustumHeight); float3 spawnPositionAlly = new Vector3(randomGenerator.NextFloat(cameraPosition.x - halfFrustumWidth, cameraPosition.x + halfFrustumWidth), yPosition, cameraPosition.z - halfFrustumHeight); //Spawn the hazard using the index we randomly generated Entity newHazardEntity = EntityManager.Instantiate(MonoBehaviourECSBridge.Instance.GetPrefabHazardEntity(spawnInfo.hazardIndexToSpawn, spawnInfo.isBackgroundSpawn == 1)); //Make sure to remove the prefab "tag" data component // EntityManager.RemoveComponent<Prefab>(newHazardEntity); //Based on the type of entity spawned, set the data needed for it EntityTypeData entityTypeData = EntityManager.GetSharedComponentData <EntityTypeData>(newHazardEntity); switch (entityTypeData.entityType) { case EntityTypeData.EntityType.Asteroid: { Vector3 spawnRenderForward = new Vector3(randomGenerator.NextFloat(), randomGenerator.NextFloat(), 1.0f); spawnRenderForward.Normalize(); Vector3 spawnRotationAxis = new Vector3(randomGenerator.NextFloat(), 1.0f, randomGenerator.NextFloat()); spawnRotationAxis.Normalize(); Position newPosition = new Position() { Value = spawnPositionHazard, }; EntityManager.SetComponentData <Position>(newHazardEntity, newPosition); Rotation newRotation = new Rotation() { Value = quaternion.LookRotation(spawnRenderForward, spawnRotationAxis), }; EntityManager.SetComponentData <Rotation>(newHazardEntity, newRotation); AsteroidMoveData moveData = EntityManager.GetComponentData <AsteroidMoveData>(newHazardEntity); moveData.movementSpeed = -forwardDirection * 5.0f; moveData.rotationAxis = spawnRotationAxis; EntityManager.SetComponentData <AsteroidMoveData>(newHazardEntity, moveData); } break; case EntityTypeData.EntityType.EnemyShip: { Position newPosition = new Position() { Value = spawnPositionHazard, }; EntityManager.SetComponentData <Position>(newHazardEntity, newPosition); Rotation newRotation = new Rotation() { Value = quaternion.LookRotation(-forwardDirection, new float3(0.0f, 1.0f, 0.0f)), }; EntityManager.SetComponentData <Rotation>(newHazardEntity, newRotation); } break; case EntityTypeData.EntityType.AllyShip: { Position newPosition = new Position() { Value = spawnPositionAlly, }; EntityManager.SetComponentData <Position>(newHazardEntity, newPosition); Rotation newRotation = new Rotation() { Value = quaternion.LookRotation(forwardDirection, new float3(0.0f, 1.0f, 0.0f)), }; EntityManager.SetComponentData <Rotation>(newHazardEntity, newRotation); } break; } } spawnerSpawnInfoList.Clear(); }