public static JobHandle ToEntityComponentMap <T>( this EntityQuery entityQuery, ref NativeHashMap <Entity, T> resultEntityComponentMap, JobHandle inputDeps) where T : struct, IComponentData { inputDeps = resultEntityComponentMap.Clear(inputDeps, entityQuery.CalculateEntityCountWithoutFiltering()); inputDeps = new GatherEntityComponentMap <T> { Result = resultEntityComponentMap.AsParallelWriter() }.Schedule(entityQuery, inputDeps); return(inputDeps); }
public static JobHandle ToEntityIndexMap( this EntityQuery entityQuery, EntityManager entityManager, ref NativeHashMap <Entity, int> resultEntityIndexMap, JobHandle inputDeps) { inputDeps = resultEntityIndexMap.Clear(inputDeps, entityQuery.CalculateEntityCountWithoutFiltering()); inputDeps = new GatherEntityIndexMap { EntityType = entityManager.GetArchetypeChunkEntityType(), EntityIndexMap = resultEntityIndexMap.AsParallelWriter() }.Schedule(entityQuery, inputDeps); return(inputDeps); }
public static JobHandle ToEntityComponentMap <T>( this EntityQuery entityQuery, EntityManager entityManager, ref NativeHashMap <Entity, T> resultEntityComponentMap, JobHandle inputDeps) where T : struct, IComponentData { inputDeps = resultEntityComponentMap.Clear(inputDeps, entityQuery.CalculateEntityCountWithoutFiltering()); inputDeps = new GatherEntityComponentMap <T> { ChunkEntityType = entityManager.GetArchetypeChunkEntityType(), ChunkDataType = entityManager.GetArchetypeChunkComponentType <T>(true), Result = resultEntityComponentMap.AsParallelWriter() }.Schedule(entityQuery, inputDeps); return(inputDeps); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { if (m_connectionGroup.IsEmptyIgnoreFilter) { // No connected players, just destroy all asteroids to save CPU inputDeps.Complete(); World.EntityManager.DestroyEntity(asteroidGroup); return(default(JobHandle)); } var settings = GetSingleton <ServerSettings>(); if (m_Prefab == Entity.Null) { m_useStaticAsteroid = settings.staticAsteroidOptimization; var prefabs = GetSingleton <GhostPrefabCollectionComponent>(); var serverPrefabs = EntityManager.GetBuffer <GhostPrefabBuffer>(prefabs.serverPrefabs); for (int i = 0; i < serverPrefabs.Length; ++i) { if (EntityManager.HasComponent <AsteroidTagComponentData>(serverPrefabs[i].Value) && (EntityManager.HasComponent <StaticAsteroid>(serverPrefabs[i].Value) == m_useStaticAsteroid)) { m_Prefab = serverPrefabs[i].Value; } } m_Radius = EntityManager.GetComponentData <CollisionSphereComponent>(m_Prefab).radius; } var maxAsteroids = settings.numAsteroids; JobHandle levelHandle; var spawnJob = new SpawnJob { commandBuffer = barrier.CreateCommandBuffer(), count = asteroidGroup.CalculateEntityCountWithoutFiltering(), targetCount = maxAsteroids, asteroidPrefab = m_Prefab, asteroidRadius = m_Radius, asteroidVelocity = settings.asteroidVelocity, level = m_LevelGroup.ToComponentDataArrayAsync <LevelComponent>(Allocator.TempJob, out levelHandle), rand = new Unity.Mathematics.Random((uint)Stopwatch.GetTimestamp()), useStaticAsteroid = m_useStaticAsteroid, tick = m_ServerSimulationSystemGroup.ServerTick }; var handle = spawnJob.Schedule(JobHandle.CombineDependencies(inputDeps, levelHandle)); barrier.AddJobHandleForProducer(handle); return(handle); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { if (m_connectionGroup.IsEmptyIgnoreFilter) { // No connected players, just destroy all asteroids to save CPU inputDeps.Complete(); World.EntityManager.DestroyEntity(asteroidGroup); return(default(JobHandle)); } if (m_Prefab == Entity.Null) { var prefabs = GetSingleton <GhostPrefabCollectionComponent>(); var serverPrefabs = EntityManager.GetBuffer <GhostPrefabBuffer>(prefabs.serverPrefabs); m_Prefab = serverPrefabs[AsteroidsGhostSerializerCollection.FindGhostType <AsteroidSnapshotData>()].Value; m_Radius = EntityManager.GetComponentData <CollisionSphereComponent>(m_Prefab).radius; } var settings = GetSingleton <ServerSettings>(); var maxAsteroids = settings.numAsteroids; JobHandle levelHandle; var spawnJob = new SpawnJob { commandBuffer = barrier.CreateCommandBuffer(), count = asteroidGroup.CalculateEntityCountWithoutFiltering(), targetCount = maxAsteroids, asteroidPrefab = m_Prefab, asteroidRadius = m_Radius, asteroidVelocity = settings.asteroidVelocity, level = m_LevelGroup.ToComponentDataArray <LevelComponent>(Allocator.TempJob, out levelHandle), rand = new Unity.Mathematics.Random((uint)Stopwatch.GetTimestamp()) }; var handle = spawnJob.Schedule(JobHandle.CombineDependencies(inputDeps, levelHandle)); barrier.AddJobHandleForProducer(handle); return(handle); }
protected override unsafe void OnUpdate() { EntityCommandBuffer commandBuffer = m_BeginSimulationBarrier.CreateCommandBuffer(); var spawnListEntity = GetSingletonEntity <PredictedGhostSpawnList>(); var spawnListFromEntity = GetBufferFromEntity <PredictedGhostSpawn>(); if (!m_GhostInitQuery.IsEmptyIgnoreFilter) { m_ChildEntityLookup.Clear(); var childCount = m_ChildEntityQuery.CalculateEntityCountWithoutFiltering(); if (childCount > m_ChildEntityLookup.Capacity) { m_ChildEntityLookup.Capacity = childCount; } var buildChildJob = new BuildChildEntityLookupJob { entityType = GetEntityTypeHandle(), childEntityLookup = m_ChildEntityLookup.AsParallelWriter() }; Dependency = buildChildJob.ScheduleParallel(m_ChildEntityQuery, Dependency); var initJob = new InitGhostJob { GhostComponentCollection = m_GhostCollectionSystem.m_GhostComponentCollection, GhostTypeCollection = m_GhostCollectionSystem.m_GhostTypeCollection, GhostComponentIndex = m_GhostCollectionSystem.m_GhostComponentIndex, entityType = GetEntityTypeHandle(), snapshotDataType = GetComponentTypeHandle <SnapshotData>(), snapshotDataBufferType = GetBufferTypeHandle <SnapshotDataBuffer>(), spawnListFromEntity = spawnListFromEntity, spawnListEntity = spawnListEntity, ghostFromEntity = GetComponentDataFromEntity <GhostComponent>(), ghostTypeFromEntity = GetComponentDataFromEntity <GhostTypeComponent>(true), ghostPrefabBufferFromEntity = GetBufferFromEntity <GhostPrefabBuffer>(true), prefabEntity = GetSingletonEntity <GhostPrefabCollectionComponent>(), commandBuffer = commandBuffer, spawnTick = m_SpawnTick, linkedEntityGroupType = GetBufferTypeHandle <LinkedEntityGroup>(), childEntityLookup = m_ChildEntityLookup }; var listLength = m_GhostCollectionSystem.m_GhostComponentCollection.Length; if (listLength <= 32) { var dynamicListJob = new InitGhostJob32 { Job = initJob }; DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List); Dependency = dynamicListJob.ScheduleSingle(m_GhostInitQuery, Dependency); } else if (listLength <= 64) { var dynamicListJob = new InitGhostJob64 { Job = initJob }; DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List); Dependency = dynamicListJob.ScheduleSingle(m_GhostInitQuery, Dependency); } else if (listLength <= 128) { var dynamicListJob = new InitGhostJob128 { Job = initJob }; DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List); Dependency = dynamicListJob.ScheduleSingle(m_GhostInitQuery, Dependency); } else { throw new System.InvalidOperationException( $"Too many ghost component types present in project, limit is {DynamicTypeList.MaxCapacity} types. This is any struct which has a field marked with GhostField attribute."); } } // Validate all ghosts in the list of predictive spawn ghosts and destroy the ones which are too old uint interpolatedTick = m_ClientSimulationSystemGroup.InterpolationTick; Dependency = Job.WithCode(() => { var spawnList = spawnListFromEntity[spawnListEntity]; for (int i = 0; i < spawnList.Length; ++i) { var ghost = spawnList[i]; if (SequenceHelpers.IsNewer(interpolatedTick, ghost.spawnTick)) { // Destroy entity and remove from list commandBuffer.DestroyEntity(ghost.entity); spawnList[i] = spawnList[spawnList.Length - 1]; spawnList.RemoveAt(spawnList.Length - 1); --i; } } }).Schedule(Dependency); m_BeginSimulationBarrier.AddJobHandleForProducer(Dependency); m_SpawnTick = m_ClientSimulationSystemGroup.ServerTick; }
protected override void OnUpdate() { if (m_ConnectionGroup.IsEmptyIgnoreFilter) { // No connected players, just destroy all asteroids to save CPU EntityManager.DestroyEntity(m_AsteroidGroup); return; } var settings = GetSingleton <ServerSettings>(); if (m_Prefab == Entity.Null) { var prefabEntity = GetSingletonEntity <GhostPrefabCollectionComponent>(); var prefabs = EntityManager.GetBuffer <GhostPrefabBuffer>(prefabEntity); for (int i = 0; i < prefabs.Length; ++i) { if (EntityManager.HasComponent <AsteroidTagComponentData>(prefabs[i].Value) && (EntityManager.HasComponent <StaticAsteroid>(prefabs[i].Value) == settings.staticAsteroidOptimization)) { m_Prefab = prefabs[i].Value; } } if (m_Prefab == Entity.Null) { return; } m_Radius = EntityManager.GetComponentData <CollisionSphereComponent>(m_Prefab).radius; } JobHandle levelHandle; var commandBuffer = m_Barrier.CreateCommandBuffer(); var count = m_AsteroidGroup.CalculateEntityCountWithoutFiltering(); var asteroidPrefab = m_Prefab; var asteroidRadius = m_Radius; var level = m_LevelGroup.ToComponentDataArrayAsync <LevelComponent>(Allocator.TempJob, out levelHandle); var rand = new Unity.Mathematics.Random((uint)Stopwatch.GetTimestamp()); var tick = m_ServerSimulationSystemGroup.ServerTick; Dependency = Job.WithDisposeOnCompletion(level).WithCode(() => { for (int i = count; i < settings.numAsteroids; ++i) { // Spawn asteroid at random pos var padding = 2 * asteroidRadius; var pos = new Translation { Value = new float3(rand.NextFloat(padding, level[0].width - padding), rand.NextFloat(padding, level[0].height - padding), 0) }; float angle = rand.NextFloat(-0.0f, 359.0f); var rot = new Rotation { Value = quaternion.RotateZ(math.radians(angle)) }; var vel = new Velocity { Value = math.mul(rot.Value, new float3(0, settings.asteroidVelocity, 0)).xy }; var e = commandBuffer.Instantiate(asteroidPrefab); commandBuffer.SetComponent(e, pos); commandBuffer.SetComponent(e, rot); if (settings.staticAsteroidOptimization) { commandBuffer.SetComponent(e, new StaticAsteroid { InitialPosition = pos.Value.xy, InitialVelocity = vel.Value, InitialAngle = angle, SpawnTick = tick }); } else { commandBuffer.SetComponent(e, vel); } } }).Schedule(JobHandle.CombineDependencies(Dependency, levelHandle)); m_Barrier.AddJobHandleForProducer(Dependency); }
protected override void OnUpdate() { //Here we check the amount of connected clients if (m_ConnectionGroup.IsEmptyIgnoreFilter) { // No connected players, just destroy all asteroids to save CPU EntityManager.DestroyEntity(m_AsteroidQuery); return; } //Here we set the prefab we will use if (m_Prefab == Entity.Null) { //We grab the converted PrefabCollection Entity's AsteroidAuthoringComponent //and set m_Prefab to its Prefab value m_Prefab = GetSingleton <AsteroidAuthoringComponent>().Prefab; //we must "return" after setting this prefab because if we were to continue into the Job //we would run into errors because the variable was JUST set (ECS funny business) //comment out return and see the error return; } //Because of how ECS works we must declare local variables that will be used within the job //You cannot "GetSingleton<GameSettingsComponent>()" from within the job, must be declared outside var settings = GetSingleton <GameSettingsComponent>(); //Here we create our commandBuffer where we will "record" our structural changes (creating an Asteroid) var commandBuffer = m_BeginSimECB.CreateCommandBuffer(); //This provides the current amount of Asteroids in the EntityQuery var count = m_AsteroidQuery.CalculateEntityCountWithoutFiltering(); //We must declare our prefab as a local variable (ECS funny business) var asteroidPrefab = m_Prefab; //We will use this to generate random positions var rand = new Unity.Mathematics.Random((uint)Stopwatch.GetTimestamp()); Job .WithCode(() => { for (int i = count; i < settings.numAsteroids; ++i) { // this is how much within perimeter asteroids start var padding = 0.1f; // we are going to have the asteroids start on the perimeter of the level // choose the x, y, z coordinate of perimeter // so the x value must be from negative levelWidth/2 to positive levelWidth/2 (within padding) var xPosition = rand.NextFloat(-1f * ((settings.levelWidth) / 2 - padding), (settings.levelWidth) / 2 - padding); // so the y value must be from negative levelHeight/2 to positive levelHeight/2 (within padding) var yPosition = rand.NextFloat(-1f * ((settings.levelHeight) / 2 - padding), (settings.levelHeight) / 2 - padding); // so the z value must be from negative levelDepth/2 to positive levelDepth/2 (within padding) var zPosition = rand.NextFloat(-1f * ((settings.levelDepth) / 2 - padding), (settings.levelDepth) / 2 - padding); //We now have xPosition, yPostiion, zPosition in the necessary range //With "chooseFace" we will decide which face of the cube the Asteroid will spawn on var chooseFace = rand.NextFloat(0, 6); //Based on what face was chosen, we x, y or z to a perimeter value //(not important to learn ECS, just a way to make an interesting prespawned shape) if (chooseFace < 1) { xPosition = -1 * ((settings.levelWidth) / 2 - padding); } else if (chooseFace < 2) { xPosition = (settings.levelWidth) / 2 - padding; } else if (chooseFace < 3) { yPosition = -1 * ((settings.levelHeight) / 2 - padding); } else if (chooseFace < 4) { yPosition = (settings.levelHeight) / 2 - padding; } else if (chooseFace < 5) { zPosition = -1 * ((settings.levelDepth) / 2 - padding); } else if (chooseFace < 6) { zPosition = (settings.levelDepth) / 2 - padding; } //we then create a new translation component with the randomly generated x, y, and z values var pos = new Translation { Value = new float3(xPosition, yPosition, zPosition) }; //on our command buffer we record creating an entity from our Asteroid prefab var e = commandBuffer.Instantiate(asteroidPrefab); //we then set the Translation component of the Asteroid prefab equal to our new translation component commandBuffer.SetComponent(e, pos); //We will now set the PhysicsVelocity of our asteroids //here we generate a random Vector3 with x, y and z between -1 and 1 var randomVel = new Vector3(rand.NextFloat(-1f, 1f), rand.NextFloat(-1f, 1f), rand.NextFloat(-1f, 1f)); //next we normalize it so it has a magnitude of 1 randomVel.Normalize(); //now we set the magnitude equal to the game settings randomVel = randomVel * settings.asteroidVelocity; //here we create a new VelocityComponent with the velocity data var vel = new PhysicsVelocity { Linear = new float3(randomVel.x, randomVel.y, randomVel.z) }; //now we set the velocity component in our asteroid prefab commandBuffer.SetComponent(e, vel); } }).Schedule(); //This will add our dependency to be played back on the BeginSimulationEntityCommandBuffer m_BeginSimECB.AddJobHandleForProducer(Dependency); }