Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using Photon.Pun;
- using UnityEngine;
- public class StateBufferModel_2 : MonoBehaviourPun, IPunObservable
- {
- [SerializeField] private float InterpolationBackTime = 0.1f;//Default 0.1, one tenth of a second
- [SerializeField] private float ExtrapolationLimit = 0.5f;
- private struct State
- {
- public double Timestamp;
- public Vector3 Position;
- public Quaternion Rotation;
- public State(double timestamp, Vector3 position,Quaternion rotation)
- {
- Timestamp = timestamp;
- Position = position;
- Rotation = rotation;
- }
- }
- private State[] m_stateBuffer = new State[20];
- private int m_stateCount = 0;
- private Vector3 m_localPosition = new Vector3(0,0,0);
- private void Update()
- {
- if (!photonView.IsMine && m_stateCount != 0)
- {
- StateInterpolation();
- }
- }
- private void StateInterpolation()
- {
- var currentTime = PhotonNetwork.Time;
- var interpolationTime = currentTime - InterpolationBackTime;
- if (m_stateBuffer[0].Timestamp > interpolationTime)
- {
- Debug.Log("Interpolation");
- for(var i = 0; i < m_stateCount;i++)
- {
- //closest state that matches network Time or use oldest state
- if (m_stateBuffer[i].Timestamp <= interpolationTime || i == m_stateCount - 1)
- {
- //closest to Network
- var lhs = m_stateBuffer[i];
- //one newer
- var rhs = m_stateBuffer[Mathf.Max(i - 1, 0)];
- //time between
- var length = rhs.Timestamp - lhs.Timestamp;
- var t = 0f;
- if (t > 0.0001)
- {
- t = (float) ((interpolationTime - lhs.Timestamp) / length);
- }
- transform.position = Vector3.Lerp(lhs.Position, rhs.Position, t);
- transform.rotation = Quaternion.Slerp(lhs.Rotation, rhs.Rotation, t);
- break;
- }
- }
- }
- else
- {
- Debug.Log("Extrapolation");
- var latestState = m_stateBuffer[0];
- var extrapolationLength = (float)(interpolationTime - latestState.Timestamp);
- if (extrapolationLength < ExtrapolationLimit)
- {
- transform.position = latestState.Position * extrapolationLength;
- transform.rotation = latestState.Rotation;
- }
- }
- }
- public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
- {
- if (stream.IsWriting)
- {
- stream.SendNext(transform.position);
- stream.SendNext(transform.rotation);
- }
- else
- {
- var pos = (Vector3) stream.ReceiveNext();
- var rot = (Quaternion) stream.ReceiveNext();
- var newState = new State(info.SentServerTime,pos,rot);
- BufferState(newState);
- for (int i=0; i<m_stateCount-1; i++){
- if (m_stateBuffer[i].Timestamp < m_stateBuffer[i+1].Timestamp)
- Debug.Log("State inconsistent");
- }
- }
- }
- /// <summary>
- /// Shift the states to the right.Storing newst at 0.
- /// </summary>
- /// <param name="state"></param>
- private void BufferState(State state)
- {
- for (var i = m_stateBuffer.Length - 1; i > 0; i--)
- {
- m_stateBuffer[i] = m_stateBuffer[i - 1];
- }
- //Newest State
- m_stateBuffer[0] = state;
- m_stateCount = Mathf.Min(m_stateCount + 1, m_stateBuffer.Length);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement