public void OnEvent(EventData photonEvent) { if (photonEvent.Code == 1) { if (!isGreen && photonView.IsMine) { StateMessage state = (StateMessage)photonEvent.CustomData; SimulateFromInput(state.getInput()); SaveCurrentStateToFile(); byte evCode = 1; RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.Others }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent(evCode, currentState, raiseEventOptions, sendOptions); } else if (isGreen && photonView.IsMine) { StateMessage state = (StateMessage)photonEvent.CustomData; if (newStateMessages != null) { newStateMessages.Enqueue(state); } } } }
void RewindState() { if (newStateMessages.Count > 0) { while (newStateMessages.Count != 0) { StateMessage state_msg = newStateMessages.Dequeue(); //uint buffer_slot = state_msg.tick_number % (uint)history.Count; Vector3 position_error = new Vector3(); position_error = state_msg.getPosition() - unConfirmedPredictions.Peek().getPosition(); float rotation_error = 1.0f - Quaternion.Dot(state_msg.getRotation(), unConfirmedPredictions.Peek().getRotation()); if (position_error.sqrMagnitude > 0.0000001f || rotation_error > 0.00001f) { // capture the current predicted pos for smoothing Vector3 prev_pos = cube_rigidbody.position + this.client_pos_error; Quaternion prev_rot = cube_rigidbody.rotation * this.client_rot_error; // rewind & replay Debug.Log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! rewind"); cube_rigidbody.position = state_msg.getPosition(); cube_rigidbody.rotation = state_msg.getRotation(); cube_rigidbody.velocity = state_msg.getVelocity(); cube_rigidbody.angularVelocity = state_msg.getVelocity_Angular(); int rewind_tick_number = (int)state_msg.tick_number; while (rewind_tick_number < tick_number) { StateMessage replay = unConfirmedPredictions.Dequeue(); AddForcesToPlayer(replay.getInput()); //for smoothig not applay dirrectly Physics.Simulate(Time.fixedDeltaTime); if (rewind_tick_number != state_msg.tick_number) { replay.setPosition(transform.position); replay.setRotation(transform.rotation); history.Add(replay); unConfirmedPredictions.Enqueue(replay); } ++rewind_tick_number; } // if more than 2ms apart, just snap if ((prev_pos - cube_rigidbody.position).sqrMagnitude >= 4.0f) { this.client_pos_error = Vector3.zero; this.client_rot_error = Quaternion.identity; } else { this.client_pos_error = prev_pos - cube_rigidbody.position; this.client_rot_error = Quaternion.Inverse(cube_rigidbody.rotation) * prev_rot; } } } } }