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(); }
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; }
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(); }