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