public override void ReadPacketStream(NetDataReader stream) { // read id of last processed move and use it to update // the buffer of stored moves SeqLastProcessed = stream.GetUShort(); _log.Debug($"SeqLastProcessed from server: {SeqLastProcessed}"); _window.AckSeq((ushort)SeqLastProcessed); // read state of player obj and set it using remainder of moves in buffer to predict again CurrentlyControlledObject.Deserialize(stream); if (_window.Count == 0) { return; } int i = _window.First; while (i != _window.Last) { CurrentlyControlledObject.ApplyMoveDirection(_window.Items[i].MoveDirection.z, _window.Items[i].MoveDirection.x); i = ++i < _window.Max ? i : 0; } }
public override void ReadPacketStream(NetDataReader stream) { // The players last 3 moves are always transmitted with the last move being the most recent _receivedPlayerInputs[0].Deserialize(stream); _receivedPlayerInputs[1].Deserialize(stream); _receivedPlayerInputs[2].Deserialize(stream); _log.Debug("Read client inputs: \n " + $"Seq: {_receivedPlayerInputs[0].Seq} Move:{_receivedPlayerInputs[0].MoveDirection}\n" + $"Seq: {_receivedPlayerInputs[1].Seq} Move:{_receivedPlayerInputs[1].MoveDirection}\n" + $"Seq: {_receivedPlayerInputs[2].Seq} Move:{_receivedPlayerInputs[2].MoveDirection}\n"); // In a 0 packet loss scenario Items [1] was last sequence and input [2] is this sequence // but we will look further back, and if they are all new then apply all 3 moves ushort nextMoveSeq = (ushort)(SeqLastProcessed + 1); _log.Debug($"LastProcessedMoveSeq: {SeqLastProcessed} NextMove: {nextMoveSeq}"); int i = 2; for (; i >= 0; i--) { _log.Debug($"_playerInputsToTransmit[{i}].seq: {_receivedPlayerInputs[i].Seq}"); if (_receivedPlayerInputs[i].Seq == nextMoveSeq) { break; } } // if nextMoveSeq isn't found then i will be -1 i = i >= 0 ? i : 0; // This should always have at least one new move but up to 3 for (int j = i; j <= 2; j++) { _log.Debug($"Looking at _playerInputsToTransmit[{j}]"); _log.Debug($"Applying input with sequence: {_receivedPlayerInputs[j].Seq} to controlled object"); _log.Debug($"Object position before: {CurrentlyControlledObject.Entity.transform.position}"); CurrentlyControlledObject.ApplyMoveDirection(_receivedPlayerInputs[j].MoveDirection.z, _receivedPlayerInputs[j].MoveDirection.x); _log.Debug($"Object position after: {CurrentlyControlledObject.Entity.transform.position}"); SeqLastProcessed = _receivedPlayerInputs[j].Seq; } }
public override void UpdateControlledObject() { // sample move UserInputSample nextSample = _window.GetNextAvailable(); if (nextSample == null) { _log.Debug("User input window was full so stopped sampling input"); return; } nextSample.UpdateFromCurrentInput(); // apply move CurrentlyControlledObject.ApplyMoveDirection(nextSample.MoveDirection.z, nextSample.MoveDirection.x); // Update packets to transmit _playerInputsToTransmit.RemoveAt(0); _playerInputsToTransmit.Add(nextSample); }