Ejemplo n.º 1
0
 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);
 }
Ejemplo n.º 2
0
 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);
 }
Ejemplo n.º 3
0
 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);
 }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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;
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
    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);
    }