예제 #1
0
        private void Rollback()
        {
            // 刷新快照的值到组件上
            NativeArray <ArchetypeChunk> ghostChunks =
                _ghostQuery.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out var ghostChunkHandle);

            ghostChunkHandle.Complete();

            var         ghostSerializerCollection = World.GetExistingSystem <GhostCollectionSystem>();
            RollbackJob rollbackJob = new RollbackJob
            {
                GhostChunks                 = ghostChunks,
                EntityTypeHandle            = GetEntityTypeHandle(),
                GhostComponentTypeHandle    = GetComponentTypeHandle <GhostComponent>(),
                SnapshotBufferTypeHandle    = GetBufferTypeHandle <SnapshotDataBuffer>(),
                SnapshotComponentTypeHandle = GetComponentTypeHandle <SnapshotData>(),
                ComponentSerializers        = ghostSerializerCollection.Serializers,
                GhostTypeCollection         = ghostSerializerCollection.GhostTypeCollection,
                ComponentIndex              = ghostSerializerCollection.IndexCollection
            };
            var listLen = ghostSerializerCollection.Serializers.Length;

            if (listLen <= 32)
            {
                var updateJob32 = new RollbackJob32 {
                    Job = rollbackJob
                };
                DynamicTypeList.PopulateList(this, ghostSerializerCollection.Serializers, false,
                                             ref updateJob32.List);
                updateJob32.Schedule().Complete();
            }

            ghostChunks.Dispose();
        }
예제 #2
0
        protected override void OnUpdate()
        {
            // 刷新快照的值到组件上
            NativeArray <ArchetypeChunk> ghostChunks =
                _ghostQuery.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out var ghostChunkHandle);

            ghostChunkHandle.Complete();

            var ghostSerializerCollection = World.GetExistingSystem <GhostCollectionSystem>();
            InterpolatedUpdateJob interpolatedUpdateJob = new InterpolatedUpdateJob
            {
                GhostChunks                    = ghostChunks,
                EntityTypeHandle               = GetEntityTypeHandle(),
                GhostComponentTypeHandle       = GetComponentTypeHandle <GhostComponent>(),
                SnapshotBufferTypeHandle       = GetBufferTypeHandle <SnapshotDataBuffer>(),
                SnapshotComponentTypeHandle    = GetComponentTypeHandle <SnapshotData>(),
                InterpolatedTargetTick         = _networkTime.interpolateTargetTick,
                InterpolatedTargetTickFraction = _networkTime.subInterpolateTargetTick,
                ComponentSerializers           = ghostSerializerCollection.Serializers,
                GhostTypeCollection            = ghostSerializerCollection.GhostTypeCollection,
                ComponentIndex                 = ghostSerializerCollection.IndexCollection
            };
            var listLen = ghostSerializerCollection.Serializers.Length;

            if (listLen <= 32)
            {
                var updateJob32 = new UpdateJob32 {
                    Job = interpolatedUpdateJob
                };
                DynamicTypeList.PopulateList(this, ghostSerializerCollection.Serializers, false,
                                             ref updateJob32.List);
                updateJob32.Schedule().Complete();
            }

            ghostChunks.Dispose();
        }
        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;
        }
예제 #4
0
        protected override void OnUpdate()
        {
            uint tick = _ghostPredictionSystemGroup.PredictingTick;

            // 新添加的ghost
            Entities.With(ghostSpawnGroup).ForEach((Entity ent, ref GhostComponent ghostComponent) =>
            {
                ++_ghostInstanceId;
                ghostComponent.Id = _ghostInstanceId;
                PostUpdateCommands.AddComponent(ent, new GhostSystemStateComponent {
                    ghostId = ghostComponent.Id
                });
                _newGhosts.Add(ghostComponent.Id, ent);
            });

            ClientServerTickRate tickRate = default;

            if (HasSingleton <ClientServerTickRate>())
            {
                tickRate = GetSingleton <ClientServerTickRate>();
            }

            tickRate.ResolveDefaults();
            int networkTickInterval = tickRate.SimulationTickRate / tickRate.NetworkTickRate;

            if (tick % networkTickInterval != 0)
            {
                return;
            }

            var localTime = NetworkTimeSystem.TimestampMS;

            // 需要发送快照的ghost chunk
            // 已经按照原型分块了
            NativeArray <ArchetypeChunk> ghostChunks =
                ghostGroup.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out JobHandle ghostChunksHandle);
            NativeArray <ArchetypeChunk> despawnChunks =
                ghostDespawnGroup.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out JobHandle despawnChunksHandle);

            JobHandle.CompleteAll(ref ghostChunksHandle, ref despawnChunksHandle);

            var connections = connectionGroup.ToEntityArray(Allocator.TempJob);

            // 获取动态组件类型
            var ghostSerializerCollectionSystem = World.GetExistingSystem <GhostCollectionSystem>();

            for (int i = 0; i < connections.Length; i++)
            {
                SerializeJob serializeJob = new SerializeJob
                {
                    ConnectionEntity     = connections[i],
                    ConnectionFromEntity = GetComponentDataFromEntity <NetworkStreamConnection>(),
                    AckFromEntity        = GetComponentDataFromEntity <NetworkSnapshotAckComponent>(),
                    LocalTime            = localTime,
                    Tick                       = tick,
                    NetDriver                  = _driver.ToConcurrent(),
                    CompressionModel           = _compressionModel,
                    UnreliablePipeline         = _unreliablePipeline,
                    GhostChunks                = ghostChunks,
                    DespawnChunks              = despawnChunks,
                    EntityTypeHandle           = GetEntityTypeHandle(),
                    GhostTypeHandle            = GetComponentTypeHandle <GhostComponent>(),
                    GhostSystemStateTypeHandle = GetComponentTypeHandle <GhostSystemStateComponent>(),
                    GhostTypeCollection        = ghostSerializerCollectionSystem.GhostTypeCollection,
                    GhostComponentIndex        = ghostSerializerCollectionSystem.IndexCollection,
                    GhostComponentSerializers  = ghostSerializerCollectionSystem.Serializers,
                };

                // FIXME
                var listLength = ghostSerializerCollectionSystem.Serializers.Length;
                if (listLength <= 32)
                {
                    var dynamicListJob = new SerializeJob32 {
                        Job = serializeJob
                    };
                    DynamicTypeList.PopulateList(this, ghostSerializerCollectionSystem.Serializers, true,
                                                 ref dynamicListJob.List);

                    dynamicListJob.Schedule().Complete();
                }
            }


            // 移除的ghost
            Entities.With(ghostDespawnGroup).ForEach((Entity ent, ref GhostSystemStateComponent state) =>
            {
                _newGhosts.Remove(state.ghostId);
                PostUpdateCommands.RemoveComponent <GhostSystemStateComponent>(ent);
            });

            connections.Dispose();
            ghostChunks.Dispose();
            despawnChunks.Dispose();
        }