示例#1
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;
        }
示例#2
0
        protected override void OnUpdate()
        {
            if (!m_GhostCollectionSystem.m_GhostTypeCollection.IsCreated)
            {
                return;
            }
            if (m_GhostPredictionSystemGroup.PredictingTick != m_GhostPredictionHistorySystem.LastBackupTick)
            {
                return;
            }

            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 smoothingJob = new PredictionSmoothingJob
            {
                predictionState    = m_GhostPredictionHistorySystem.PredictionState,
                ghostType          = GetComponentTypeHandle <GhostComponent>(true),
                predictedGhostType = GetComponentTypeHandle <PredictedGhostComponent>(true),
                entityType         = GetEntityTypeHandle(),

                GhostComponentCollection = m_GhostCollectionSystem.m_GhostComponentCollection,
                GhostTypeCollection      = m_GhostCollectionSystem.m_GhostTypeCollection,
                GhostComponentIndex      = m_GhostCollectionSystem.m_GhostComponentIndex,

                childEntityLookup     = m_ChildEntityLookup,
                linkedEntityGroupType = GetBufferTypeHandle <LinkedEntityGroup>(),
                tick = m_GhostPredictionSystemGroup.PredictingTick,

                translationType = ComponentType.ReadWrite <Translation>()
            };

            Dependency = JobHandle.CombineDependencies(Dependency, m_GhostPredictionHistorySystem.PredictionStateWriteJobHandle);

            var listLength = m_GhostCollectionSystem.m_GhostComponentCollection.Length;

            if (listLength <= 32)
            {
                var dynamicListJob = new PredictionSmoothingJob32 {
                    Job = smoothingJob
                };
                DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List);
                Dependency = dynamicListJob.ScheduleParallel(m_PredictionQuery, Dependency);
            }
            else if (listLength <= 64)
            {
                var dynamicListJob = new PredictionSmoothingJob64 {
                    Job = smoothingJob
                };
                DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List);
                Dependency = dynamicListJob.ScheduleParallel(m_PredictionQuery, Dependency);
            }
            else if (listLength <= 128)
            {
                var dynamicListJob = new PredictionSmoothingJob128 {
                    Job = smoothingJob
                };
                DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List);
                Dependency = dynamicListJob.ScheduleParallel(m_PredictionQuery, 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.");
            }

            m_GhostPredictionHistorySystem.AddPredictionStateReader(Dependency);
        }
        protected override void OnUpdate()
        {
            if (!m_GhostCollectionSystem.m_GhostTypeCollection.IsCreated)
            {
                return;
            }

            var serverTick = m_ClientSimulationSystemGroup.ServerTick;

            if (m_ClientSimulationSystemGroup.ServerTickFraction < 1)
            {
                --serverTick;
            }
            if (serverTick != m_GhostPredictionSystemGroup.PredictingTick)
            {
                return;
            }
            LastBackupTick = serverTick;

            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 predictionState          = PredictionState;
            var newPredictionState       = m_NewPredictionState;
            var stillUsedPredictionState = m_StillUsedPredictionState;

            stillUsedPredictionState.Clear();
            if (stillUsedPredictionState.Capacity < predictionState.Capacity)
            {
                stillUsedPredictionState.Capacity = predictionState.Capacity;
            }
            var backupJob = new PredictionBackupJob
            {
                predictionState          = predictionState,
                stillUsedPredictionState = stillUsedPredictionState.AsParallelWriter(),
                newPredictionState       = newPredictionState.AsParallelWriter(),
                ghostType  = GetComponentTypeHandle <GhostComponent>(true),
                entityType = GetEntityTypeHandle(),

                GhostComponentCollection = m_GhostCollectionSystem.m_GhostComponentCollection,
                GhostTypeCollection      = m_GhostCollectionSystem.m_GhostTypeCollection,
                GhostComponentIndex      = m_GhostCollectionSystem.m_GhostComponentIndex,

                childEntityLookup     = m_ChildEntityLookup,
                linkedEntityGroupType = GetBufferTypeHandle <LinkedEntityGroup>(),
            };

            Dependency = JobHandle.CombineDependencies(Dependency, m_PredictionStateReadJobHandle);
            m_PredictionStateReadJobHandle = default;

            var listLength = m_GhostCollectionSystem.m_GhostComponentCollection.Length;

            if (listLength <= 32)
            {
                var dynamicListJob = new PredictionBackupJob32 {
                    Job = backupJob
                };
                DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List);
                Dependency = dynamicListJob.ScheduleParallel(m_PredictionQuery, Dependency);
            }
            else if (listLength <= 64)
            {
                var dynamicListJob = new PredictionBackupJob64 {
                    Job = backupJob
                };
                DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List);
                Dependency = dynamicListJob.ScheduleParallel(m_PredictionQuery, Dependency);
            }
            else if (listLength <= 128)
            {
                var dynamicListJob = new PredictionBackupJob128 {
                    Job = backupJob
                };
                DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List);
                Dependency = dynamicListJob.ScheduleParallel(m_PredictionQuery, 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.");
            }

            Job.WithCode(() => {
                var keys = predictionState.GetKeyArray(Allocator.Temp);
                for (int i = 0; i < keys.Length; ++i)
                {
                    if (!stillUsedPredictionState.TryGetValue(keys[i], out var temp))
                    {
                        // Free the memory and remove the chunk from the lookup
                        predictionState.TryGetValue(keys[i], out var alloc);
                        UnsafeUtility.Free((void *)alloc, Allocator.Persistent);
                        predictionState.Remove(keys[i]);
                    }
                }
                while (newPredictionState.TryDequeue(out var newState))
                {
                    if (!predictionState.TryAdd(newState.chunk, newState.data))
                    {
                        // Remove the old value, free it and add the new one - this happens when a chunk is reused too quickly
                        predictionState.TryGetValue(newState.chunk, out var alloc);
                        UnsafeUtility.Free((void *)alloc, Allocator.Persistent);
                        predictionState.Remove(newState.chunk);
                        // And add it again
                        predictionState.TryAdd(newState.chunk, newState.data);
                    }
                }
            }).Schedule();

            PredictionStateWriteJobHandle = Dependency;
        }
示例#4
0
        protected override void OnUpdate()
        {
            if (!m_GhostCollectionSystem.m_GhostTypeCollection.IsCreated)
            {
                return;
            }
            if (m_GhostPredictionSystemGroup.PredictingTick != m_GhostPredictionHistorySystem.LastBackupTick)
            {
                return;
            }

            if (m_PredictionErrors.Length != m_GhostCollectionSystem.PredictionErrorCount * JobsUtility.MaxJobThreadCount)
            {
                m_PredictionErrors.Dispose();
                m_PredictionErrors = new NativeArray <float>(m_GhostCollectionSystem.PredictionErrorCount * JobsUtility.MaxJobThreadCount, Allocator.Persistent);
            }
            for (int job = 1; job < JobsUtility.MaxJobThreadCount; ++job)
            {
                for (int i = 0; i < m_GhostCollectionSystem.PredictionErrorCount; ++i)
                {
                    m_PredictionErrors[i] = math.max(m_PredictionErrors[i], m_PredictionErrors[m_GhostCollectionSystem.PredictionErrorCount * job + i]);
                }
            }
            World.GetExistingSystem <GhostStatsCollectionSystem>().AddPredictionErrorStats(m_PredictionErrors.GetSubArray(0, m_GhostCollectionSystem.PredictionErrorCount));
            // Clear
            UnsafeUtility.MemClear(m_PredictionErrors.GetUnsafePtr(), 4 * m_GhostCollectionSystem.PredictionErrorCount * JobsUtility.MaxJobThreadCount);

            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 debugJob = new PredictionDebugJob
            {
                predictionState    = m_GhostPredictionHistorySystem.PredictionState,
                ghostType          = GetComponentTypeHandle <GhostComponent>(true),
                predictedGhostType = GetComponentTypeHandle <PredictedGhostComponent>(true),
                entityType         = GetEntityTypeHandle(),

                GhostComponentCollection = m_GhostCollectionSystem.m_GhostComponentCollection,
                GhostTypeCollection      = m_GhostCollectionSystem.m_GhostTypeCollection,
                GhostComponentIndex      = m_GhostCollectionSystem.m_GhostComponentIndex,

                childEntityLookup     = m_ChildEntityLookup,
                linkedEntityGroupType = GetBufferTypeHandle <LinkedEntityGroup>(),
                tick            = m_GhostPredictionSystemGroup.PredictingTick,
                translationType = ComponentType.ReadWrite <Translation>(),

                predictionErrors    = m_PredictionErrors,
                numPredictionErrors = m_GhostCollectionSystem.PredictionErrorCount
            };

            Dependency = JobHandle.CombineDependencies(Dependency, m_GhostPredictionHistorySystem.PredictionStateWriteJobHandle);

            var listLength = m_GhostCollectionSystem.m_GhostComponentCollection.Length;

            if (listLength <= 32)
            {
                var dynamicListJob = new PredictionDebugJob32 {
                    Job = debugJob
                };
                DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List);
                Dependency = dynamicListJob.ScheduleParallel(m_PredictionQuery, Dependency);
            }
            else if (listLength <= 64)
            {
                var dynamicListJob = new PredictionDebugJob64 {
                    Job = debugJob
                };
                DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List);
                Dependency = dynamicListJob.ScheduleParallel(m_PredictionQuery, Dependency);
            }
            else if (listLength <= 128)
            {
                var dynamicListJob = new PredictionDebugJob128 {
                    Job = debugJob
                };
                DynamicTypeList.PopulateList(this, m_GhostCollectionSystem.m_GhostComponentCollection, true, ref dynamicListJob.List);
                Dependency = dynamicListJob.ScheduleParallel(m_PredictionQuery, 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.");
            }

            m_GhostPredictionHistorySystem.AddPredictionStateReader(Dependency);
        }