Exemple #1
0
    protected override void OnUpdate()
    {
        //This is the NetCode recommended method to identify predicted spawning for player spawned objects
        //More information can be found at: https://docs.unity3d.com/Packages/[email protected]/manual/ghost-snapshots.html
        //under "Entity spawning"
        var spawnListEntity     = GetSingletonEntity <PredictedGhostSpawnList>();
        var spawnListFromEntity = GetBufferFromEntity <PredictedGhostSpawn>();

        Dependency = Entities
                     .WithAll <GhostSpawnQueueComponent>()
                     .WithoutBurst()
                     .ForEach((DynamicBuffer <GhostSpawnBuffer> ghosts, DynamicBuffer <SnapshotDataBuffer> data) =>
        {
            var spawnList = spawnListFromEntity[spawnListEntity];
            for (int i = 0; i < ghosts.Length; ++i)
            {
                var ghost = ghosts[i];
                if (ghost.SpawnType == GhostSpawnBuffer.Type.Predicted)
                {
                    for (int j = 0; j < spawnList.Length; ++j)
                    {
                        if (ghost.GhostType == spawnList[j].ghostType && !SequenceHelpers.IsNewer(spawnList[j].spawnTick, ghost.ServerSpawnTick + 5) && SequenceHelpers.IsNewer(spawnList[j].spawnTick + 5, ghost.ServerSpawnTick))
                        {
                            ghost.PredictedSpawnEntity = spawnList[j].entity;
                            spawnList[j] = spawnList[spawnList.Length - 1];
                            spawnList.RemoveAt(spawnList.Length - 1);
                            break;
                        }
                    }
                    ghosts[i] = ghost;
                }
            }
        }).Schedule(Dependency);
    }
Exemple #2
0
    public bool IsReceivedByRemote(uint tick)
    {
        if (tick == 0 || LastReceivedSnapshotByRemote == 0)
        {
            return(false);
        }
        if (SequenceHelpers.IsNewer(tick, LastReceivedSnapshotByRemote))
        {
            return(false);
        }
        int bit = (int)(LastReceivedSnapshotByRemote - tick);

        if (bit >= 256)
        {
            return(false);
        }
        if (bit >= 192)
        {
            bit -= 192;
            return((ReceivedSnapshotByRemoteMask3 & (1ul << bit)) != 0);
        }
        if (bit >= 128)
        {
            bit -= 128;
            return((ReceivedSnapshotByRemoteMask2 & (1ul << bit)) != 0);
        }
        if (bit >= 64)
        {
            bit -= 64;
            return((ReceivedSnapshotByRemoteMask1 & (1ul << bit)) != 0);
        }
        return((ReceivedSnapshotByRemoteMask0 & (1ul << bit)) != 0);
    }
Exemple #3
0
            public void Execute()
            {
                var keys = predictionSpawnCleanupMap.GetKeyArray(Allocator.Temp);

                for (var i = 0; i < keys.Length; ++i)
                {
                    predictionSpawnGhosts[keys[i]] = default(PredictSpawnGhost);
                }
                for (int i = 0; i < predictionSpawnGhosts.Length; ++i)
                {
                    if (predictionSpawnGhosts[i].entity != Entity.Null &&
                        SequenceHelpers.IsNewer(interpolationTarget, predictionSpawnGhosts[i].snapshotData.Tick))
                    {
                        // Trigger a delete of the entity
                        commandBuffer.RemoveComponent(predictionSpawnGhosts[i].entity, ghostComponentType);
                        predictionSpawnGhosts[i] = default(PredictSpawnGhost);
                    }

                    if (predictionSpawnGhosts[i].entity == Entity.Null)
                    {
                        predictionSpawnGhosts.RemoveAtSwapBack(i);
                        --i;
                    }
                }
            }
Exemple #4
0
        protected override void OnUpdate()
        {
            // Gather the min/max age stats
            var intsPerCacheLine = JobsUtility.CacheLineSize / 4;

            for (int i = 1; i < JobsUtility.MaxJobThreadCount; ++i)
            {
                if (m_ghostSnapshotTickMinMax[intsPerCacheLine * i] != 0 &&
                    (m_ghostSnapshotTickMinMax[0] == 0 ||
                     SequenceHelpers.IsNewer(m_ghostSnapshotTickMinMax[0], m_ghostSnapshotTickMinMax[intsPerCacheLine * i])))
                {
                    m_ghostSnapshotTickMinMax[0] = m_ghostSnapshotTickMinMax[intsPerCacheLine * i];
                }
                if (m_ghostSnapshotTickMinMax[intsPerCacheLine * i + 1] != 0 &&
                    (m_ghostSnapshotTickMinMax[1] == 0 ||
                     SequenceHelpers.IsNewer(m_ghostSnapshotTickMinMax[intsPerCacheLine * i + 1], m_ghostSnapshotTickMinMax[1])))
                {
                    m_ghostSnapshotTickMinMax[1] = m_ghostSnapshotTickMinMax[intsPerCacheLine * i + 1];
                }
                m_ghostSnapshotTickMinMax[intsPerCacheLine * i]     = 0;
                m_ghostSnapshotTickMinMax[intsPerCacheLine * i + 1] = 0;
            }
            // Pass the min and max to stats collection
            m_GhostStatsCollectionSystem.SetSnapshotTick(m_ghostSnapshotTickMinMax[0], m_ghostSnapshotTickMinMax[1]);
            m_ghostSnapshotTickMinMax[0] = 0;
            m_ghostSnapshotTickMinMax[1] = 0;
            base.OnUpdate();
        }
Exemple #5
0
        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            var deserializerState = new GhostDeserializerState
            {
                GhostMap = GhostMap
            };
            var ghostEntityArray       = chunk.GetNativeArray(ghostEntityType);
            var ghostSnapshotDataArray = chunk.GetBufferAccessor(ghostSnapshotDataType);

#if UNITY_EDITOR || DEVELOPMENT_BUILD
            var minMaxOffset = ThreadIndex * (JobsUtility.CacheLineSize / 4);
#endif
            for (int entityIndex = 0; entityIndex < ghostEntityArray.Length; ++entityIndex)
            {
                var snapshot = ghostSnapshotDataArray[entityIndex];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                var latestTick = snapshot.GetLatestTick();
                if (latestTick != 0)
                {
                    if (minMaxSnapshotTick[minMaxOffset] == 0 || SequenceHelpers.IsNewer(minMaxSnapshotTick[minMaxOffset], latestTick))
                    {
                        minMaxSnapshotTick[minMaxOffset] = latestTick;
                    }
                    if (minMaxSnapshotTick[minMaxOffset + 1] == 0 || SequenceHelpers.IsNewer(latestTick, minMaxSnapshotTick[minMaxOffset + 1]))
                    {
                        minMaxSnapshotTick[minMaxOffset + 1] = latestTick;
                    }
                }
#endif
                LobbyConnectionGhostSnapshotData snapshotData;
                snapshot.GetDataAtTick(targetTick, targetTickFraction, out snapshotData);
            }
        }
        protected override void OnUpdate()
        {
            uint interpolatedTick = _networkTimeSystem.interpolateTargetTick;
            uint predictedTick    = _networkTimeSystem.predictTargetTick;
            var  commandBuffer    = _barrier.CreateCommandBuffer();

            // 插值类型的Ghost销毁
            while (_interpolatedDespawnQueue.Count > 0 &&
                   !SequenceHelpers.IsNewer(_interpolatedDespawnQueue.Peek().Tick, interpolatedTick))
            {
                var desspawnGhost = _interpolatedDespawnQueue.Dequeue();
                if (_ghostReceiveSystem.SpawnedGhostEntityMap.TryGetValue(desspawnGhost.Ghost, out Entity ent))
                {
                    commandBuffer.DestroyEntity(ent);
                    _ghostReceiveSystem.SpawnedGhostEntityMap.Remove(desspawnGhost.Ghost);
                }
            }

            // 预测类型的Ghost销毁
            while (_predictedDespawnQueue.Count > 0 &&
                   !SequenceHelpers.IsNewer(_predictedDespawnQueue.Peek().Tick, predictedTick))
            {
                var desspawnGhost = _predictedDespawnQueue.Dequeue();
                if (_ghostReceiveSystem.SpawnedGhostEntityMap.TryGetValue(desspawnGhost.Ghost, out Entity ent))
                {
                    commandBuffer.DestroyEntity(ent);
                    _ghostReceiveSystem.SpawnedGhostEntityMap.Remove(desspawnGhost.Ghost);
                }
            }
        }
        public static bool GetDataAtTick <T>(this DynamicBuffer <T> commandArray, uint targetTick, out T commandData)
            where T : struct, ICommandData <T>
        {
            int  beforeIdx  = 0;
            uint beforeTick = 0;

            for (int i = 0; i < commandArray.Length; ++i)
            {
                uint tick = commandArray[i].Tick;
                if (!SequenceHelpers.IsNewer(tick, targetTick) &&
                    (beforeTick == 0 || SequenceHelpers.IsNewer(tick, beforeTick)))
                {
                    beforeIdx  = i;
                    beforeTick = tick;
                }
            }

            if (beforeTick == 0)
            {
                commandData = default(T);
                return(false);
            }

            commandData = commandArray[beforeIdx];
            return(true);
        }
        public static void AddCommandData <T>(this DynamicBuffer <T> commandArray, T commandData)
            where T : struct, ICommandData <T>
        {
            uint targetTick = commandData.Tick;
            int  oldestIdx  = 0;
            uint oldestTick = 0;

            for (int i = 0; i < commandArray.Length; ++i)
            {
                uint tick = commandArray[i].Tick;
                if (tick == targetTick)
                {
                    // Already exists, replace it
                    commandArray[i] = commandData;
                    return;
                }

                if (oldestTick == 0 || SequenceHelpers.IsNewer(oldestTick, tick))
                {
                    oldestIdx  = i;
                    oldestTick = tick;
                }
            }

            if (commandArray.Length < k_CommandDataMaxSize)
            {
                commandArray.Add(commandData);
            }
            else
            {
                commandArray[oldestIdx] = commandData;
            }
        }
Exemple #9
0
            public void Execute([ReadOnly] DynamicBuffer <TSnapshot> snapshots, ref TComponent component, ref Predicted <TSnapshot> predictedData, ref GhostPredictedComponent globalPredicted)
            {
                snapshots.GetDataAtTick(targetTick, out var snapshotData);

                var lastPredictedTickInst = lastPredictTick;

                if (lastPredictedTickInst == 0 || predictedData.AppliedTick != snapshotData.Tick)
                {
                    lastPredictedTickInst = snapshotData.Tick;
                }
                else if (!SequenceHelpers.IsNewer(lastPredictedTickInst, snapshotData.Tick))
                {
                    lastPredictedTickInst = snapshotData.Tick;
                }
                if (minPredictedTick[ThreadIndex] == 0 || SequenceHelpers.IsNewer(minPredictedTick[ThreadIndex], lastPredictedTickInst))
                {
                    minPredictedTick[ThreadIndex] = lastPredictedTickInst;
                }

                predictedData = new Predicted <TSnapshot> {
                    AppliedTick = snapshotData.Tick, PredictionStartTick = lastPredictedTickInst
                };
                globalPredicted.AppliedTick         = predictedData.AppliedTick;
                globalPredicted.PredictionStartTick = predictedData.PredictionStartTick;

                if (lastPredictedTickInst != snapshotData.Tick)
                {
                    return;
                }

                snapshotData.SynchronizeTo(ref component, jobData);
            }
Exemple #10
0
        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            var deserializerState = new GhostDeserializerState
            {
                GhostMap = GhostMap
            };
            var ghostEntityArray             = chunk.GetNativeArray(ghostEntityType);
            var ghostSnapshotDataArray       = chunk.GetBufferAccessor(ghostSnapshotDataType);
            var ghostHealthArray             = chunk.GetNativeArray(ghostHealthType);
            var ghostPlayerUnitArray         = chunk.GetNativeArray(ghostPlayerUnitType);
            var ghostUnitSelectionStateArray = chunk.GetNativeArray(ghostUnitSelectionStateType);
            var ghostLinkedEntityGroupArray  = chunk.GetBufferAccessor(ghostLinkedEntityGroupType);

#if UNITY_EDITOR || DEVELOPMENT_BUILD
            var minMaxOffset = ThreadIndex * (JobsUtility.CacheLineSize / 4);
#endif
            for (int entityIndex = 0; entityIndex < ghostEntityArray.Length; ++entityIndex)
            {
                var snapshot = ghostSnapshotDataArray[entityIndex];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                var latestTick = snapshot.GetLatestTick();
                if (latestTick != 0)
                {
                    if (minMaxSnapshotTick[minMaxOffset] == 0 || SequenceHelpers.IsNewer(minMaxSnapshotTick[minMaxOffset], latestTick))
                    {
                        minMaxSnapshotTick[minMaxOffset] = latestTick;
                    }
                    if (minMaxSnapshotTick[minMaxOffset + 1] == 0 || SequenceHelpers.IsNewer(latestTick, minMaxSnapshotTick[minMaxOffset + 1]))
                    {
                        minMaxSnapshotTick[minMaxOffset + 1] = latestTick;
                    }
                }
#endif
                _UnitSnapshotData snapshotData;
                snapshot.GetDataAtTick(targetTick, targetTickFraction, out snapshotData);

                var ghostHealth             = ghostHealthArray[entityIndex];
                var ghostPlayerUnit         = ghostPlayerUnitArray[entityIndex];
                var ghostUnitSelectionState = ghostUnitSelectionStateArray[entityIndex];
                var ghostRotation           = ghostRotationFromEntity[ghostLinkedEntityGroupArray[entityIndex][0].Value];
                var ghostTranslation        = ghostTranslationFromEntity[ghostLinkedEntityGroupArray[entityIndex][0].Value];
                var ghostChild0Rotation     = ghostRotationFromEntity[ghostLinkedEntityGroupArray[entityIndex][1].Value];
                var ghostChild0Translation  = ghostTranslationFromEntity[ghostLinkedEntityGroupArray[entityIndex][1].Value];
                ghostHealth.Value                  = snapshotData.GetHealthValue(deserializerState);
                ghostPlayerUnit.PlayerId           = snapshotData.GetPlayerUnitPlayerId(deserializerState);
                ghostPlayerUnit.UnitId             = snapshotData.GetPlayerUnitUnitId(deserializerState);
                ghostUnitSelectionState.IsSelected = snapshotData.GetUnitSelectionStateIsSelected(deserializerState);
                ghostRotation.Value                = snapshotData.GetRotationValue(deserializerState);
                ghostTranslation.Value             = snapshotData.GetTranslationValue(deserializerState);
                ghostChild0Rotation.Value          = snapshotData.GetChild0RotationValue(deserializerState);
                ghostChild0Translation.Value       = snapshotData.GetChild0TranslationValue(deserializerState);
                ghostRotationFromEntity[ghostLinkedEntityGroupArray[entityIndex][0].Value]    = ghostRotation;
                ghostTranslationFromEntity[ghostLinkedEntityGroupArray[entityIndex][0].Value] = ghostTranslation;
                ghostRotationFromEntity[ghostLinkedEntityGroupArray[entityIndex][1].Value]    = ghostChild0Rotation;
                ghostTranslationFromEntity[ghostLinkedEntityGroupArray[entityIndex][1].Value] = ghostChild0Translation;
                ghostHealthArray[entityIndex]             = ghostHealth;
                ghostPlayerUnitArray[entityIndex]         = ghostPlayerUnit;
                ghostUnitSelectionStateArray[entityIndex] = ghostUnitSelectionState;
            }
        }
    protected override void OnUpdate()
    {
        var spawnListEntity     = GetSingletonEntity <PredictedGhostSpawnList>();
        var spawnListFromEntity = GetBufferFromEntity <PredictedGhostSpawn>();

        Dependency = Entities
                     .WithAll <GhostSpawnQueueComponent>()
                     .WithoutBurst()
                     .ForEach((DynamicBuffer <GhostSpawnBuffer> ghosts, DynamicBuffer <SnapshotDataBuffer> data) =>
        {
            var spawnList = spawnListFromEntity[spawnListEntity];
            for (int i = 0; i < ghosts.Length; ++i)
            {
                var ghost = ghosts[i];
                if (ghost.SpawnType == GhostSpawnBuffer.Type.Predicted)
                {
                    for (int j = 0; j < spawnList.Length; ++j)
                    {
                        if (ghost.GhostType == spawnList[j].ghostType && !SequenceHelpers.IsNewer(spawnList[j].spawnTick, ghost.ServerSpawnTick + 5) && SequenceHelpers.IsNewer(spawnList[j].spawnTick + 5, ghost.ServerSpawnTick))
                        {
                            ghost.PredictedSpawnEntity = spawnList[j].entity;
                            spawnList[j] = spawnList[spawnList.Length - 1];
                            spawnList.RemoveAt(spawnList.Length - 1);
                            break;
                        }
                    }
                    ghosts[i] = ghost;
                }
            }
        }).Schedule(Dependency);
    }
Exemple #12
0
        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            var deserializerState = new GhostDeserializerState
            {
                GhostMap = GhostMap
            };
            var ghostEntityArray                   = chunk.GetNativeArray(ghostEntityType);
            var ghostSnapshotDataArray             = chunk.GetBufferAccessor(ghostSnapshotDataType);
            var ghostHealthComponentArray          = chunk.GetNativeArray(ghostHealthComponentType);
            var ghostProgressionComponentArray     = chunk.GetNativeArray(ghostProgressionComponentType);
            var ghostSynchronizedCarComponentArray = chunk.GetNativeArray(ghostSynchronizedCarComponentType);
            var ghostRotationArray                 = chunk.GetNativeArray(ghostRotationType);
            var ghostTranslationArray              = chunk.GetNativeArray(ghostTranslationType);

#if UNITY_EDITOR || DEVELOPMENT_BUILD
            var minMaxOffset = ThreadIndex * (JobsUtility.CacheLineSize / 4);
#endif
            for (int entityIndex = 0; entityIndex < ghostEntityArray.Length; ++entityIndex)
            {
                var snapshot = ghostSnapshotDataArray[entityIndex];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                var latestTick = snapshot.GetLatestTick();
                if (latestTick != 0)
                {
                    if (minMaxSnapshotTick[minMaxOffset] == 0 || SequenceHelpers.IsNewer(minMaxSnapshotTick[minMaxOffset], latestTick))
                    {
                        minMaxSnapshotTick[minMaxOffset] = latestTick;
                    }
                    if (minMaxSnapshotTick[minMaxOffset + 1] == 0 || SequenceHelpers.IsNewer(latestTick, minMaxSnapshotTick[minMaxOffset + 1]))
                    {
                        minMaxSnapshotTick[minMaxOffset + 1] = latestTick;
                    }
                }
#endif
                // If there is no data found don't apply anything (would be default state), required for prespawned ghosts
                CarStubSnapshotData snapshotData;
                if (!snapshot.GetDataAtTick(targetTick, targetTickFraction, out snapshotData))
                {
                    return;
                }

                var ghostHealthComponent          = ghostHealthComponentArray[entityIndex];
                var ghostProgressionComponent     = ghostProgressionComponentArray[entityIndex];
                var ghostSynchronizedCarComponent = ghostSynchronizedCarComponentArray[entityIndex];
                var ghostRotation    = ghostRotationArray[entityIndex];
                var ghostTranslation = ghostTranslationArray[entityIndex];
                ghostHealthComponent.Health = snapshotData.GetHealthComponentHealth(deserializerState);
                ghostProgressionComponent.CrossedCheckpoints = snapshotData.GetProgressionComponentCrossedCheckpoints(deserializerState);
                ghostSynchronizedCarComponent.PlayerId       = snapshotData.GetSynchronizedCarComponentPlayerId(deserializerState);
                ghostSynchronizedCarComponent.SteerAngle     = snapshotData.GetSynchronizedCarComponentSteerAngle(deserializerState);
                ghostSynchronizedCarComponent.IsShieldActive = snapshotData.GetSynchronizedCarComponentIsShieldActive(deserializerState);
                ghostRotation.Value    = snapshotData.GetRotationValue(deserializerState);
                ghostTranslation.Value = snapshotData.GetTranslationValue(deserializerState);
                ghostHealthComponentArray[entityIndex]          = ghostHealthComponent;
                ghostProgressionComponentArray[entityIndex]     = ghostProgressionComponent;
                ghostSynchronizedCarComponentArray[entityIndex] = ghostSynchronizedCarComponent;
                ghostRotationArray[entityIndex]    = ghostRotation;
                ghostTranslationArray[entityIndex] = ghostTranslation;
            }
        }
        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            var deserializerState = new GhostDeserializerState
            {
                GhostMap = GhostMap
            };
            var ghostEntityArray         = chunk.GetNativeArray(ghostEntityType);
            var ghostSnapshotDataArray   = chunk.GetBufferAccessor(ghostSnapshotDataType);
            var ghostCameraRigChildArray = chunk.GetNativeArray(ghostCameraRigChildType);
            var ghostPilotDataArray      = chunk.GetNativeArray(ghostPilotDataType);
            var ghostRotationArray       = chunk.GetNativeArray(ghostRotationType);
            var ghostTranslationArray    = chunk.GetNativeArray(ghostTranslationType);

#if UNITY_EDITOR || DEVELOPMENT_BUILD
            var minMaxOffset = ThreadIndex * (JobsUtility.CacheLineSize / 4);
#endif
            for (int entityIndex = 0; entityIndex < ghostEntityArray.Length; ++entityIndex)
            {
                var snapshot = ghostSnapshotDataArray[entityIndex];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                var latestTick = snapshot.GetLatestTick();
                if (latestTick != 0)
                {
                    if (minMaxSnapshotTick[minMaxOffset] == 0 || SequenceHelpers.IsNewer(minMaxSnapshotTick[minMaxOffset], latestTick))
                    {
                        minMaxSnapshotTick[minMaxOffset] = latestTick;
                    }
                    if (minMaxSnapshotTick[minMaxOffset + 1] == 0 || SequenceHelpers.IsNewer(latestTick, minMaxSnapshotTick[minMaxOffset + 1]))
                    {
                        minMaxSnapshotTick[minMaxOffset + 1] = latestTick;
                    }
                }
#endif
                // If there is no data found don't apply anything (would be default state), required for prespawned ghosts
                PilotSnapshotData snapshotData;
                if (!snapshot.GetDataAtTick(targetTick, targetTickFraction, out snapshotData))
                {
                    return;
                }

                var ghostCameraRigChild = ghostCameraRigChildArray[entityIndex];
                var ghostPilotData      = ghostPilotDataArray[entityIndex];
                var ghostRotation       = ghostRotationArray[entityIndex];
                var ghostTranslation    = ghostTranslationArray[entityIndex];
                ghostCameraRigChild.headPose      = snapshotData.GetCameraRigChildheadPose(deserializerState);
                ghostCameraRigChild.headRot       = snapshotData.GetCameraRigChildheadRot(deserializerState);
                ghostCameraRigChild.leftHandPose  = snapshotData.GetCameraRigChildleftHandPose(deserializerState);
                ghostCameraRigChild.leftHandRot   = snapshotData.GetCameraRigChildleftHandRot(deserializerState);
                ghostCameraRigChild.rightHandPose = snapshotData.GetCameraRigChildrightHandPose(deserializerState);
                ghostCameraRigChild.rightHandRot  = snapshotData.GetCameraRigChildrightHandRot(deserializerState);
                ghostPilotData.PlayerId           = snapshotData.GetPilotDataPlayerId(deserializerState);
                ghostRotation.Value    = snapshotData.GetRotationValue(deserializerState);
                ghostTranslation.Value = snapshotData.GetTranslationValue(deserializerState);
                ghostCameraRigChildArray[entityIndex] = ghostCameraRigChild;
                ghostPilotDataArray[entityIndex]      = ghostPilotData;
                ghostRotationArray[entityIndex]       = ghostRotation;
                ghostTranslationArray[entityIndex]    = ghostTranslation;
            }
        }
        public void UpdateReceivedByRemote(uint tick, uint mask)
        {
            if (tick == 0)
            {
                ReceivedSnapshotByRemoteMask3 = 0;
                ReceivedSnapshotByRemoteMask2 = 0;
                ReceivedSnapshotByRemoteMask1 = 0;
                ReceivedSnapshotByRemoteMask0 = 0;
                LastReceivedSnapshotByRemote  = 0;
            }
            else if (LastReceivedSnapshotByRemote == 0)
            {
                ReceivedSnapshotByRemoteMask3 = 0;
                ReceivedSnapshotByRemoteMask2 = 0;
                ReceivedSnapshotByRemoteMask1 = 0;
                ReceivedSnapshotByRemoteMask0 = mask;
                LastReceivedSnapshotByRemote  = tick;
            }
            else if (SequenceHelpers.IsNewer(tick, LastReceivedSnapshotByRemote))
            {
                int shamt = (int)(tick - LastReceivedSnapshotByRemote);
                if (shamt >= 256)
                {
                    ReceivedSnapshotByRemoteMask3 = 0;
                    ReceivedSnapshotByRemoteMask2 = 0;
                    ReceivedSnapshotByRemoteMask1 = 0;
                    ReceivedSnapshotByRemoteMask0 = mask;
                }
                else
                {
                    while (shamt >= 64)
                    {
                        ReceivedSnapshotByRemoteMask3 = ReceivedSnapshotByRemoteMask2;
                        ReceivedSnapshotByRemoteMask2 = ReceivedSnapshotByRemoteMask1;
                        ReceivedSnapshotByRemoteMask1 = ReceivedSnapshotByRemoteMask0;
                        ReceivedSnapshotByRemoteMask0 = 0;
                        shamt -= 64;
                    }

                    if (shamt == 0)
                    {
                        ReceivedSnapshotByRemoteMask0 |= mask;
                    }
                    else
                    {
                        ReceivedSnapshotByRemoteMask3 = (ReceivedSnapshotByRemoteMask3 << shamt) |
                                                        (ReceivedSnapshotByRemoteMask2 >> (64 - shamt));
                        ReceivedSnapshotByRemoteMask2 = (ReceivedSnapshotByRemoteMask2 << shamt) |
                                                        (ReceivedSnapshotByRemoteMask1 >> (64 - shamt));
                        ReceivedSnapshotByRemoteMask1 = (ReceivedSnapshotByRemoteMask1 << shamt) |
                                                        (ReceivedSnapshotByRemoteMask0 >> (64 - shamt));
                        ReceivedSnapshotByRemoteMask0 = (ReceivedSnapshotByRemoteMask0 << shamt) |
                                                        mask;
                    }
                }

                LastReceivedSnapshotByRemote = tick;
            }
        }
Exemple #15
0
 // This is updated on both server and client side, used to track RTT on both sides.
 // It is updated when receiving command or snapshot.
 //
 // public void UpdateRemoteTime(uint remoteTime, uint localTimeMinusRTT, uint localTime)
 // TODO: LZ:
 //      to be confirmed: fix RTT calculation:
 //      A                           B
 //      t0: A send time
 //                                  T0: B receive time
 //                                  T1: B send time
 //      t1: A receive time
 public void UpdateRemoteTime(uint remoteTime, uint localSentPlusRomoteProcess, uint localTime)
 {
     if (remoteTime != 0 && SequenceHelpers.IsNewer(remoteTime, LastReceivedRemoteTime))
     {
         LastReceivedRemoteTime = remoteTime;
         LastReceivedRTT        = localTime - localSentPlusRomoteProcess; // t1 - (t0 + (T1 - T0))
         LastReceiveTimestamp   = localTime;
     }
 }
Exemple #16
0
        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            var deserializerState = new GhostDeserializerState
            {
                GhostMap = GhostMap
            };
            var ghostEntityArray       = chunk.GetNativeArray(ghostEntityType);
            var ghostSnapshotDataArray = chunk.GetBufferAccessor(ghostSnapshotDataType);
            var ghostPlayerStateArray  = chunk.GetNativeArray(ghostPlayerStateType);

#if UNITY_EDITOR || DEVELOPMENT_BUILD
            var minMaxOffset = ThreadIndex * (JobsUtility.CacheLineSize / 4);
#endif
            for (int entityIndex = 0; entityIndex < ghostEntityArray.Length; ++entityIndex)
            {
                var snapshot = ghostSnapshotDataArray[entityIndex];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                var latestTick = snapshot.GetLatestTick();
                if (latestTick != 0)
                {
                    if (minMaxSnapshotTick[minMaxOffset] == 0 || SequenceHelpers.IsNewer(minMaxSnapshotTick[minMaxOffset], latestTick))
                    {
                        minMaxSnapshotTick[minMaxOffset] = latestTick;
                    }
                    if (minMaxSnapshotTick[minMaxOffset + 1] == 0 || SequenceHelpers.IsNewer(latestTick, minMaxSnapshotTick[minMaxOffset + 1]))
                    {
                        minMaxSnapshotTick[minMaxOffset + 1] = latestTick;
                    }
                }
#endif
                PlayerStateSnapshotData snapshotData;
                snapshot.GetDataAtTick(targetTick, targetTickFraction, out snapshotData);

                var ghostPlayerState = ghostPlayerStateArray[entityIndex];
                ghostPlayerState.playerId   = snapshotData.GetPlayerStateplayerId(deserializerState);
                ghostPlayerState.playerName = snapshotData.GetPlayerStateplayerName(deserializerState);
                ghostPlayerState.teamIndex  = snapshotData.GetPlayerStateteamIndex(deserializerState);
                ghostPlayerState.score      = snapshotData.GetPlayerStatescore(deserializerState);
                ghostPlayerState.gameModeSystemInitialized = snapshotData.GetPlayerStategameModeSystemInitialized(deserializerState);
                ghostPlayerState.displayCountDown          = snapshotData.GetPlayerStatedisplayCountDown(deserializerState);
                ghostPlayerState.countDown          = snapshotData.GetPlayerStatecountDown(deserializerState);
                ghostPlayerState.displayScoreBoard  = snapshotData.GetPlayerStatedisplayScoreBoard(deserializerState);
                ghostPlayerState.displayGameScore   = snapshotData.GetPlayerStatedisplayGameScore(deserializerState);
                ghostPlayerState.displayGameResult  = snapshotData.GetPlayerStatedisplayGameResult(deserializerState);
                ghostPlayerState.gameResult         = snapshotData.GetPlayerStategameResult(deserializerState);
                ghostPlayerState.displayGoal        = snapshotData.GetPlayerStatedisplayGoal(deserializerState);
                ghostPlayerState.goalPosition       = snapshotData.GetPlayerStategoalPosition(deserializerState);
                ghostPlayerState.goalDefendersColor = snapshotData.GetPlayerStategoalDefendersColor(deserializerState);
                ghostPlayerState.goalAttackersColor = snapshotData.GetPlayerStategoalAttackersColor(deserializerState);
                ghostPlayerState.goalAttackers      = snapshotData.GetPlayerStategoalAttackers(deserializerState);
                ghostPlayerState.goalDefenders      = snapshotData.GetPlayerStategoalDefenders(deserializerState);
                ghostPlayerState.goalString         = snapshotData.GetPlayerStategoalString(deserializerState);
                ghostPlayerState.actionString       = snapshotData.GetPlayerStateactionString(deserializerState);
                ghostPlayerState.goalCompletion     = snapshotData.GetPlayerStategoalCompletion(deserializerState);
                ghostPlayerStateArray[entityIndex]  = ghostPlayerState;
            }
        }
Exemple #17
0
 public void UpdateRemoteTime(uint remoteTime, uint localTimeMinusRTT, uint localTime)
 {
     if (remoteTime != 0 && SequenceHelpers.IsNewer(remoteTime, LastReceivedRemoteTime))
     {
         LastReceivedRemoteTime = remoteTime;
         LastReceivedRTT        = localTime - localTimeMinusRTT;
         LastReceiveTimestamp   = localTime;
     }
 }
Exemple #18
0
        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            var deserializerState = new GhostDeserializerState
            {
                GhostMap = GhostMap
            };
            var ghostEntityArray             = chunk.GetNativeArray(ghostEntityType);
            var ghostSnapshotDataArray       = chunk.GetBufferAccessor(ghostSnapshotDataType);
            var predictedGhostComponentArray = chunk.GetNativeArray(predictedGhostComponentType);

#if UNITY_EDITOR || DEVELOPMENT_BUILD
            var minMaxOffset = ThreadIndex * (JobsUtility.CacheLineSize / 4);
#endif
            for (int entityIndex = 0; entityIndex < ghostEntityArray.Length; ++entityIndex)
            {
                var snapshot = ghostSnapshotDataArray[entityIndex];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                var latestTick = snapshot.GetLatestTick();
                if (latestTick != 0)
                {
                    if (minMaxSnapshotTick[minMaxOffset] == 0 || SequenceHelpers.IsNewer(minMaxSnapshotTick[minMaxOffset], latestTick))
                    {
                        minMaxSnapshotTick[minMaxOffset] = latestTick;
                    }
                    if (minMaxSnapshotTick[minMaxOffset + 1] == 0 || SequenceHelpers.IsNewer(latestTick, minMaxSnapshotTick[minMaxOffset + 1]))
                    {
                        minMaxSnapshotTick[minMaxOffset + 1] = latestTick;
                    }
                }
#endif
                SpawnerSnapshotData snapshotData;
                snapshot.GetDataAtTick(targetTick, out snapshotData);

                var predictedData         = predictedGhostComponentArray[entityIndex];
                var lastPredictedTickInst = lastPredictedTick;
                if (lastPredictedTickInst == 0 || predictedData.AppliedTick != snapshotData.Tick)
                {
                    lastPredictedTickInst = snapshotData.Tick;
                }
                else if (!SequenceHelpers.IsNewer(lastPredictedTickInst, snapshotData.Tick))
                {
                    lastPredictedTickInst = snapshotData.Tick;
                }
                if (minPredictedTick[ThreadIndex] == 0 || SequenceHelpers.IsNewer(minPredictedTick[ThreadIndex], lastPredictedTickInst))
                {
                    minPredictedTick[ThreadIndex] = lastPredictedTickInst;
                }
                predictedGhostComponentArray[entityIndex] = new PredictedGhostComponent {
                    AppliedTick = snapshotData.Tick, PredictionStartTick = lastPredictedTickInst
                };
                if (lastPredictedTickInst != snapshotData.Tick)
                {
                    continue;
                }
            }
        }
        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            var deserializerState = new GhostDeserializerState
            {
                GhostMap = GhostMap
            };
            var ghostEntityArray       = chunk.GetNativeArray(ghostEntityType);
            var ghostSnapshotDataArray = chunk.GetBufferAccessor(ghostSnapshotDataType);
            var ghostPlayerDataArray   = chunk.GetNativeArray(ghostPlayerDataType);
            var ghostRotationArray     = chunk.GetNativeArray(ghostRotationType);
            var ghostTranslationArray  = chunk.GetNativeArray(ghostTranslationType);

#if UNITY_EDITOR || DEVELOPMENT_BUILD
            var minMaxOffset = ThreadIndex * (JobsUtility.CacheLineSize / 4);
#endif
            for (int entityIndex = 0; entityIndex < ghostEntityArray.Length; ++entityIndex)
            {
                var snapshot = ghostSnapshotDataArray[entityIndex];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                var latestTick = snapshot.GetLatestTick();
                if (latestTick != 0)
                {
                    if (minMaxSnapshotTick[minMaxOffset] == 0 || SequenceHelpers.IsNewer(minMaxSnapshotTick[minMaxOffset], latestTick))
                    {
                        minMaxSnapshotTick[minMaxOffset] = latestTick;
                    }
                    if (minMaxSnapshotTick[minMaxOffset + 1] == 0 || SequenceHelpers.IsNewer(latestTick, minMaxSnapshotTick[minMaxOffset + 1]))
                    {
                        minMaxSnapshotTick[minMaxOffset + 1] = latestTick;
                    }
                }
#endif
                SphereSnapshotData snapshotData;
                snapshot.GetDataAtTick(targetTick, targetTickFraction, out snapshotData);

                var ghostPlayerData  = ghostPlayerDataArray[entityIndex];
                var ghostRotation    = ghostRotationArray[entityIndex];
                var ghostTranslation = ghostTranslationArray[entityIndex];
                ghostPlayerData.playerId           = snapshotData.GetPlayerDataplayerId(deserializerState);
                ghostPlayerData.maxHealth          = snapshotData.GetPlayerDatamaxHealth(deserializerState);
                ghostPlayerData.currentHealth      = snapshotData.GetPlayerDatacurrentHealth(deserializerState);
                ghostPlayerData.death              = snapshotData.GetPlayerDatadeath(deserializerState);
                ghostPlayerData.auto               = snapshotData.GetPlayerDataauto(deserializerState);
                ghostPlayerData.autoSpawn          = snapshotData.GetPlayerDataautoSpawn(deserializerState);
                ghostPlayerData.dest               = snapshotData.GetPlayerDatadest(deserializerState);
                ghostPlayerData.dest2              = snapshotData.GetPlayerDatadest2(deserializerState);
                ghostPlayerData.killedBy           = snapshotData.GetPlayerDatakilledBy(deserializerState);
                ghostPlayerData.killedByID         = snapshotData.GetPlayerDatakilledByID(deserializerState);
                ghostRotation.Value                = snapshotData.GetRotationValue(deserializerState);
                ghostTranslation.Value             = snapshotData.GetTranslationValue(deserializerState);
                ghostPlayerDataArray[entityIndex]  = ghostPlayerData;
                ghostRotationArray[entityIndex]    = ghostRotation;
                ghostTranslationArray[entityIndex] = ghostTranslation;
            }
        }
        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            var deserializerState = new GhostDeserializerState
            {
                GhostMap = GhostMap
            };
            var ghostEntityArray       = chunk.GetNativeArray(ghostEntityType);
            var ghostSnapshotDataArray = chunk.GetBufferAccessor(ghostSnapshotDataType);

            #region __GHOST_INTERPOLATED_COMPONENT_ARRAY__
            var ghost__GHOST_COMPONENT_TYPE_NAME__Array = chunk.GetNativeArray(ghost__GHOST_COMPONENT_TYPE_NAME__Type);
            #endregion
            #region __GHOST_INTERPOLATED_BUFFER_ARRAY__
            var ghost__GHOST_COMPONENT_TYPE_NAME__Array = chunk.GetBufferAccessor(ghost__GHOST_COMPONENT_TYPE_NAME__Type);
            #endregion
#if UNITY_EDITOR || DEVELOPMENT_BUILD
            var minMaxOffset = ThreadIndex * (JobsUtility.CacheLineSize / 4);
#endif
            for (int entityIndex = 0; entityIndex < ghostEntityArray.Length; ++entityIndex)
            {
                var snapshot = ghostSnapshotDataArray[entityIndex];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                var latestTick = snapshot.GetLatestTick();
                if (latestTick != 0)
                {
                    if (minMaxSnapshotTick[minMaxOffset] == 0 || SequenceHelpers.IsNewer(minMaxSnapshotTick[minMaxOffset], latestTick))
                    {
                        minMaxSnapshotTick[minMaxOffset] = latestTick;
                    }
                    if (minMaxSnapshotTick[minMaxOffset + 1] == 0 || SequenceHelpers.IsNewer(latestTick, minMaxSnapshotTick[minMaxOffset + 1]))
                    {
                        minMaxSnapshotTick[minMaxOffset + 1] = latestTick;
                    }
                }
#endif
                __GHOST_NAME__SnapshotData snapshotData;
                snapshot.GetDataAtTick(targetTick, targetTickFraction, out snapshotData);

                #region __GHOST_INTERPOLATED_BEGIN_ASSIGN__
                var ghost__GHOST_COMPONENT_TYPE_NAME__ = ghost__GHOST_COMPONENT_TYPE_NAME__Array[entityIndex];
                #endregion
                #region __GHOST_INTERPOLATED_BEGIN_ASSIGN_CHILD__
                var ghost__GHOST_COMPONENT_TYPE_NAME__ = ghost__GHOST_COMPONENT_FROM_ENTITY_NAME__FromEntity[ghostLinkedEntityGroupArray[entityIndex][__GHOST_ENTITY_INDEX__].Value];
                #endregion
                #region __GHOST_INTERPOLATED_ASSIGN__
                ghost__GHOST_COMPONENT_TYPE_NAME__.__GHOST_FIELD_NAME__ = snapshotData.Get__GHOST_COMPONENT_TYPE_NAME____GHOST_FIELD_NAME__(deserializerState);
                #endregion
                #region __GHOST_INTERPOLATED_END_ASSIGN_CHILD__
                ghost__GHOST_COMPONENT_FROM_ENTITY_NAME__FromEntity[ghostLinkedEntityGroupArray[entityIndex][__GHOST_ENTITY_INDEX__].Value] = ghost__GHOST_COMPONENT_TYPE_NAME__;
                #endregion
                #region __GHOST_INTERPOLATED_END_ASSIGN__
                ghost__GHOST_COMPONENT_TYPE_NAME__Array[entityIndex] = ghost__GHOST_COMPONENT_TYPE_NAME__;
                #endregion
            }
        }
        public static bool TryGetName(this Link link, out string str)
        {
            // Защита от зацикливания
            if (!_linksWithNamesGatheringProcess.Add(link))
            {
                str = "...";
                return(true);
            }
            try
            {
                if (link != null)
                {
                    if (link.Linker == Net.And)
                    {
                        str = SequenceHelpers.FormatSequence(link);
                        return(true);
                    }
                    else if (link.IsGroup())
                    {
                        str = LinkConverter.ToString(LinkConverter.ToList(link.Target));
                        return(true);
                    }
                    else if (link.IsChar())
                    {
                        str = LinkConverter.ToChar(link).ToString();
                        return(true);
                    }
                    else if (link.TryGetSpecificName(out str))
                    {
                        return(true);
                    }

                    if (link.Source == link || link.Linker == link || link.Target == link)
                    {
                        return(false);
                    }

                    if (link.Source.TryGetName(out string sourceName) && link.Linker.TryGetName(out string linkerName) && link.Target.TryGetName(out string targetName))
                    {
                        var sb = new StringBuilder();
                        sb.Append(sourceName).Append(' ').Append(linkerName).Append(' ').Append(targetName);
                        str = sb.ToString();
                        return(true);
                    }
                }
                str = null;
                return(false);
            }
            finally
            {
                _linksWithNamesGatheringProcess.Remove(link);
            }
        }
Exemple #22
0
        public static bool GetDataAtTick <T>(this DynamicBuffer <T> snapshotArray, uint targetTick,
                                             float targetTickFraction, out T snapshotData) where T : struct, ISnapshotData <T>
        {
            int  beforeIdx  = 0;
            uint beforeTick = 0;
            int  afterIdx   = 0;
            uint afterTick  = 0;

            // If last tick is fractional before should not include the tick we are targeting, it should instead be included in after
            if (targetTickFraction < 1)
            {
                --targetTick;
            }
            for (int i = 0; i < snapshotArray.Length; ++i)
            {
                uint tick = snapshotArray[i].Tick;
                if (!SequenceHelpers.IsNewer(tick, targetTick) &&
                    (beforeTick == 0 || SequenceHelpers.IsNewer(tick, beforeTick)))
                {
                    beforeIdx  = i;
                    beforeTick = tick;
                }

                if (SequenceHelpers.IsNewer(tick, targetTick) &&
                    (afterTick == 0 || SequenceHelpers.IsNewer(afterTick, tick)))
                {
                    afterIdx  = i;
                    afterTick = tick;
                }
            }

            if (beforeTick == 0)
            {
                snapshotData = default(T);
                return(false);
            }

            snapshotData = snapshotArray[beforeIdx];
            if (afterTick == 0)
            {
                return(true);
            }
            var   after       = snapshotArray[afterIdx];
            float afterWeight = (float)(targetTick - beforeTick) / (float)(afterTick - beforeTick);

            if (targetTickFraction < 1)
            {
                afterWeight += targetTickFraction / (float)(afterTick - beforeTick);
            }
            snapshotData.Interpolate(ref after, afterWeight);
            return(true);
        }
Exemple #23
0
            public void Execute()
            {
                while (interpolatedDespawnQueue.Count > 0 &&
                       !SequenceHelpers.IsNewer(interpolatedDespawnQueue.Peek().tick, interpolatedTick))
                {
                    commandBuffer.RemoveComponent(interpolatedDespawnQueue.Dequeue().ghost, ghostType);
                }

                while (predictedDespawnQueue.Count > 0 &&
                       !SequenceHelpers.IsNewer(predictedDespawnQueue.Peek().tick, predictedTick))
                {
                    commandBuffer.RemoveComponent(predictedDespawnQueue.Dequeue().ghost, ghostType);
                }
            }
Exemple #24
0
            public void Execute(Entity entity, int index, ref GhostSystemStateComponent ghost)
            {
                uint ackedByAllTick = tick[0];

                if (ghost.despawnTick == 0)
                {
                    ghost.despawnTick = currentTick;
                }
                else if (ackedByAllTick != 0 && !SequenceHelpers.IsNewer(ghost.despawnTick, ackedByAllTick))
                {
                    freeGhostIds.Enqueue(ghost.ghostId);
                    commandBuffer.RemoveComponent(index, entity, ghostStateType);
                }
            }
Exemple #25
0
            public void Execute([ReadOnly] ref NetworkSnapshotAckComponent ack)
            {
                uint ackedByAllTick = tick[0];
                var  snapshot       = ack.LastReceivedSnapshotByRemote;

                if (snapshot == 0)
                {
                    ackedByAllTick = 0;
                }
                else if (ackedByAllTick != 0 && SequenceHelpers.IsNewer(ackedByAllTick, snapshot))
                {
                    ackedByAllTick = snapshot;
                }
                tick[0] = ackedByAllTick;
            }
Exemple #26
0
 public void UpdateReceivedByRemote(uint tick)
 {
     if (tick == 0)
     {
         LastReceivedSnapshotByRemote = 0;
     }
     else if (LastReceivedSnapshotByRemote == 0)
     {
         LastReceivedSnapshotByRemote = tick;
     }
     else if (SequenceHelpers.IsNewer(tick, LastReceivedSnapshotByRemote))
     {
         LastReceivedSnapshotByRemote = tick;
     }
 }
Exemple #27
0
        public void GetCollisionWorldFromTick(uint tick, uint interpolationDelay, out CollisionWorld collWorld)
        {
            // Clamp to oldest physics copy when requesting older data than supported
            if (interpolationDelay > m_size - 1)
            {
                interpolationDelay = (uint)m_size - 1;
            }
            tick -= interpolationDelay;
            if (SequenceHelpers.IsNewer(tick, m_lastStoredTick))
            {
                tick = m_lastStoredTick;
            }
            var index = (int)(tick % m_size);

            GetCollisionWorldFromIndex(index, out collWorld);
        }
Exemple #28
0
        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            GhostDeserializerState deserializerState = new GhostDeserializerState
            {
                GhostMap = GhostMap
            };
            NativeArray <Entity> ghostEntityArray = chunk.GetNativeArray(ghostEntityType);
            BufferAccessor <NetCodePlayModeTestGhostObjectSnapshotData> ghostSnapshotDataArray =
                chunk.GetBufferAccessor(ghostSnapshotDataType);
            NativeArray <Rotation>    ghostRotationArray    = chunk.GetNativeArray(ghostRotationType);
            NativeArray <Translation> ghostTranslationArray = chunk.GetNativeArray(ghostTranslationType);

#if UNITY_EDITOR || DEVELOPMENT_BUILD
            int minMaxOffset = ThreadIndex * (JobsUtility.CacheLineSize / 4);
#endif
            for (int entityIndex = 0; entityIndex < ghostEntityArray.Length; ++entityIndex)
            {
                DynamicBuffer <NetCodePlayModeTestGhostObjectSnapshotData>
                snapshot = ghostSnapshotDataArray[entityIndex];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                uint latestTick = snapshot.GetLatestTick();
                if (latestTick != 0)
                {
                    if (minMaxSnapshotTick[minMaxOffset] == 0 ||
                        SequenceHelpers.IsNewer(minMaxSnapshotTick[minMaxOffset], latestTick))
                    {
                        minMaxSnapshotTick[minMaxOffset] = latestTick;
                    }

                    if (minMaxSnapshotTick[minMaxOffset + 1] == 0 ||
                        SequenceHelpers.IsNewer(latestTick, minMaxSnapshotTick[minMaxOffset + 1]))
                    {
                        minMaxSnapshotTick[minMaxOffset + 1] = latestTick;
                    }
                }
#endif
                NetCodePlayModeTestGhostObjectSnapshotData snapshotData;
                snapshot.GetDataAtTick(targetTick, targetTickFraction, out snapshotData);

                Rotation    ghostRotation    = ghostRotationArray[entityIndex];
                Translation ghostTranslation = ghostTranslationArray[entityIndex];
                ghostRotation.Value                = snapshotData.GetRotationValue(deserializerState);
                ghostTranslation.Value             = snapshotData.GetTranslationValue(deserializerState);
                ghostRotationArray[entityIndex]    = ghostRotation;
                ghostTranslationArray[entityIndex] = ghostTranslation;
            }
        }
        protected override void OnUpdate()
        {
            if (_isServer)
            {
                this.PredictingTick = World.GetExistingSystem <ServerSimulationSystemGroup>().Tick;
                NetDebug.ServerTick = this.PredictingTick;
                base.OnUpdate();
                return;
            }

            //====================================================================================
            IsFixError = false;

            NetworkSnapshotAckComponent ack = GetSingleton <NetworkSnapshotAckComponent>();
            uint targetTick = _tickSimulationSystemGroup.ServerTick;

            if (!SequenceHelpers.IsNewer(targetTick, ack.LastReceivedSnapshotByLocal))
            {
                return;
            }

            if (!SequenceHelpers.IsNewer(ack.LastReceivedSnapshotByLocal, LastAppliedSnapshotTick))
            {
                LitUpdate(targetTick);
                return;
            }

            LastAppliedSnapshotTick = ack.LastReceivedSnapshotByLocal;
            if (targetTick - LastAppliedSnapshotTick > GlobalConstants.CommandDataMaxSize)
            {
                LastAppliedSnapshotTick = targetTick - GlobalConstants.CommandDataMaxSize;
            }

            IsRewind = true;
            // Debug.Log($"开始回滚:{LastAppliedSnapshotTick + 1} to {targetTick}, PredictingTick={PredictingTick}");
            for (uint i = LastAppliedSnapshotTick + 1; i != targetTick; ++i)
            {
                LitUpdate(i);
            }

            IsRewind = false;
            // Debug.Log($"回滚结束:{PredictingTick}");

            IsFixError = true;
            LitUpdate(targetTick);
        }
Exemple #30
0
    private static int Solution1(string[] input)
    {
        TargetArea targetArea = new(input[0]);
        int        xDirection = Math.Sign(targetArea.XFrom);
        int        minX       = Math.Min(Math.Abs(targetArea.XFrom), Math.Abs(targetArea.XFrom));

        int xVelocity;

        for (xVelocity = 1; SequenceHelpers.TriangularNumber(xVelocity) < minX; xVelocity++)
        {
        }
        Point initialVelocity = new(xVelocity * xDirection, Math.Abs(targetArea.YFrom) - 1);

        (_, int height) = targetArea.WillProbeHit(initialVelocity);

        return(height);
    }