void ServerUpdate()
        {
            while (_serverPredictedMessageBuffer.Count > 0 && _networkClock.CurrentTime >=
                   _serverPredictedMessageBuffer.Peek().Element.deliveryTime)
            {
                ClientPredictedMessage clientPredictedMessage = _serverPredictedMessageBuffer.Dequeue().Element;

                // message contains an array of inputs, calculate what tick the final one is
                uint maxTick = clientPredictedMessage.startTickNumber + (uint)clientPredictedMessage.inputs.Length - 1;

                // if that tick is greater than or equal to the current tick we're on, then it
                // has inputs which are new
                if (maxTick >= _currentTickNumber)
                {
                    // there may be some inputs in the array that we've already had,
                    // so figure out where to start
                    uint startIndex = _currentTickNumber > clientPredictedMessage.startTickNumber
                        ? (_currentTickNumber - clientPredictedMessage.startTickNumber)
                        : 0;

                    // run through all relevant inputs, and step player forward
                    for (int i = (int)startIndex; i < clientPredictedMessage.inputs.Length; ++i)
                    {
                        _currentTickNumber++;
                        InputProcessorComponent.ExecuteInputs(clientPredictedMessage.inputs[i]);
                    }
                }
            }
        }
        void ClientUpdate()
        {
            _clientTimer += Time.deltaTime;

            while (_clientTimer >= Time.fixedDeltaTime)
            {
                _clientTimer -= Time.deltaTime;

                uint bufferSlot = _currentTickNumber % _clientBufferSize;

                _clientInputBuffer[bufferSlot] = InputProcessorComponent.GetCurrentInputs();

                // store state for this tick, then use current state + input to step simulation
                ClientStoreCurrentStateAndStep(ref _clientStateBuffer[bufferSlot],
                                               InputProcessorComponent.GetCurrentInputs());

                ClientPredictedMessage clientPredictedMessage = new ClientPredictedMessage();
                clientPredictedMessage.packetId        = _clientPacketID;
                clientPredictedMessage.deliveryTime    = _networkClock.CurrentTime;
                clientPredictedMessage.startTickNumber = _sendRedundantInputsToServer
                    ? _clientLastReceivedStateTickNumber
                    : _currentTickNumber;

                var inputList = new List <Inputs>();

                for (uint tick = clientPredictedMessage.startTickNumber; tick <= _currentTickNumber; tick++)
                {
                    inputList.Add(_clientInputBuffer[tick % _clientBufferSize]);
                }

                clientPredictedMessage.inputs = inputList.ToArray();

                //Send Input Message To Server
                connectionToServer.Send(_predictedMessageReceivedID, clientPredictedMessage);

                _clientPacketID++;

                _currentTickNumber++;
            }

            if (ClientHasStateMessage())
            {
                ServerStateMessage serverStateMessage = _clientServerStateMessageBuffer.Dequeue().Element;

                while (ClientHasStateMessage()
                       ) // make sure if there are any newer state messages available, we use those instead
                {
                    serverStateMessage = _clientServerStateMessageBuffer.Dequeue().Element;
                }

                _clientLastReceivedStateTickNumber = serverStateMessage.tickNumber;

                //Broadcast this server state for easy access for debugging purposes
                if (OnValidSercerStateReceived != null)
                {
                    OnValidSercerStateReceived(serverStateMessage.serverState);
                }
                //-----------------------------

                uint bufferSlot = serverStateMessage.tickNumber % _clientBufferSize;

                Vector3 positionError =
                    serverStateMessage.serverState.position - _clientStateBuffer[bufferSlot].position;

                float rotationError = 1.0f - Quaternion.Dot(serverStateMessage.serverState.rotation,
                                                            _clientStateBuffer[bufferSlot].rotation);

                //Validating position,rotation and extras rules defined in de State processor
                if (positionError.sqrMagnitude > 0.0000001f || rotationError > 0.00001f ||
                    !StateProcessorComponent.IsValidateState(ref serverStateMessage.serverState,
                                                             ref _clientStateBuffer[bufferSlot]))
                {
                    ApplyCorrectionsWithServerState(serverStateMessage, bufferSlot);
                }
            }

            SmoothTransformForModels();
        }