Beispiel #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;
        }
        protected override void OnUpdate()
        {
            var ent           = GetSingletonEntity <PredictedGhostSpawnList>();
            var spawnList     = EntityManager.GetBuffer <PredictedGhostSpawn>(ent);
            var commandBuffer = _barrier.CreateCommandBuffer();

            if (!_ghostInitQuery.IsEmptyIgnoreFilter)
            {
                var ghostChunks = _ghostInitQuery.CreateArchetypeChunkArray(Allocator.TempJob);

                var initGhostJob = new InitGhostJob
                {
                    SpawnTick                    = _spawnTick,
                    GhostChunks                  = ghostChunks,
                    EntityTypeHandle             = GetEntityTypeHandle(),
                    GhostTypeCollection          = _ghostCollectionSystem.GhostTypeCollection,
                    GhostTypeHandle              = GetComponentTypeHandle <GhostComponent>(),
                    SnapshotDataTypeHandle       = GetComponentTypeHandle <SnapshotData>(),
                    SnapshotDataBufferTypeHandle = GetBufferTypeHandle <SnapshotDataBuffer>(),
                    CommandBuffer                = commandBuffer,
                    SpawnListEntity              = ent,
                    SpawnList                    = GetBufferFromEntity <PredictedGhostSpawn>()
                };

                initGhostJob.Schedule().Complete();
                ghostChunks.Dispose();
            }

            // 本地复制到快照中
            if (!_ghostQuery.IsEmptyIgnoreFilter && _ghostPredictionSystemGroup.PredictingTick % 5 == 0)
            {
                var ghostChunks = _ghostQuery.CreateArchetypeChunkArray(Allocator.TempJob);

                var localCopyToSnapshotJob = new LocalCopyToSnapshotJob
                {
                    Tick                         = _spawnTick,
                    GhostChunks                  = ghostChunks,
                    EntityTypeHandle             = GetEntityTypeHandle(),
                    GhostTypeCollection          = _ghostCollectionSystem.GhostTypeCollection,
                    GhostTypeHandle              = GetComponentTypeHandle <GhostComponent>(),
                    SnapshotDataTypeHandle       = GetComponentTypeHandle <SnapshotData>(),
                    SnapshotDataBufferTypeHandle = GetBufferTypeHandle <SnapshotDataBuffer>(),
                    GhostComponentIndex          = _ghostCollectionSystem.IndexCollection,
                    GhostComponentSerializers    = _ghostCollectionSystem.Serializers
                };

                var listLength = _ghostCollectionSystem.Serializers.Length;
                if (listLength <= 32)
                {
                    var dynamicListJob = new LocalCopyToSnapshotJob32 {
                        Job = localCopyToSnapshotJob
                    };
                    DynamicTypeList.PopulateList(this, _ghostCollectionSystem.Serializers, true,
                                                 ref dynamicListJob.List);
                    dynamicListJob.Schedule().Complete();
                }

                ghostChunks.Dispose();
            }

            // 验证预测生成的Ghost列表中的所有Ghost,并销毁那些过旧的Ghost
            uint interpolatedTick = World.GetExistingSystem <NetworkTimeSystem>().interpolateTargetTick;

            for (int i = 0; i < spawnList.Length; i++)
            {
                var ghost = spawnList[i];
                if (SequenceHelpers.IsNewer(interpolatedTick, ghost.SpawnTick))
                {
                    commandBuffer.DestroyEntity(ghost.Entity);
                    spawnList[i] = spawnList[spawnList.Length - 1];
                    spawnList.RemoveAt(spawnList.Length - 1);
                    --i;
                }
            }

            _spawnTick = _ghostPredictionSystemGroup.PredictingTick;
        }