View difference between Paste ID: nrPq2F3N and cJq9jya3
SHOW: | | - or go back to the newest paste.
1
using UnityEngine;
2
using System.Collections;
3
4
//Predictor script for client 
5
//with client side prediction
6
7
public class C_Predictor : MonoBehaviour {
8
9
	public float pingMargin = 0.5f;
10
	
11
	private float clientPing;
12
	
13
	private NetState[] serverStateBuffer = new NetState[20];
14
	
15
	private NetState[] clientStateBuffer = new NetState[20];
16
	
17
	//Keep track of what Slots are used
18
	private int m_LocalStateCount;
19
	
20
	// Stat variabels for prediction stuff
21
    private float m_TimeAccuracy = 0;
22
    private float m_PredictionAccuracy = 0;
23
    private bool m_FixError = false;
24
    private Vector3 m_NewPosition;
25
	private Quaternion m_NewRotation;
26
	
27
	// The position vector distance to start error correction. The higher the latency the higher this
28
    // value should be or it constantly tries to correct errors in prediction
29
    public float m_PredictionThreshold = 0.3F;
30
31
	// Time difference in milliseconds where we check for error in position. If the server time value
32
    // of a state is too different from the local state time then the error correction comparison is
33
    // highly unreliable and might try to correct more errors than there really are.
34
    public float m_TimeThreshold = 0.05F;
35
36
	
37
	
38
	public void uLink_OnSerializeNetworkView(uLink.BitStream stream, uLink.NetworkMessageInfo info)
39
	{
40
		if(!stream.isWriting)
41
		{
42
			Vector3 pos = Vector3.zero;
43
			Quaternion rot = Quaternion.identity;
44
			
45
			stream.Serialize(ref pos, 0.001f);
46
			stream.Serialize(ref rot, 0.001f);
47
			
48-
			//receiver.serverPos = pos;
48+
49-
			//receiver.serverRot = rot;
49+
50
			for(int i = serverStateBuffer.Length - 1; i >= 1; i--)
51-
			//smoothly correct client pos
51+
52-
			//receiver.lerpToTarget(); //Bug lerp immediately the player to the final pos and with the interpolation the player return back
52+
53
			}
54
			
55
			//Override the first element with the latest server info
56
			serverStateBuffer[0] = new NetState((float)info.timestamp, pos, rot);
57
			
58
			/*int m_TimestampCount;
59
			for(int i = 0; i < m_TimestampCount-1; i++)
60
			{
61
				if(serverStateBuffer[i].timeStamp < serverStateBuffer[i + 1].timeStamp)
62
				{
63
					Debug.Log("State inconsistent");	
64
				}
65
			}*/
66
			
67
		}
68
		
69
	}
70
	
71
	// Use this for initialization
72
	void Start () 
73
	{
74
		StartCoroutine(StoreLocalMovement());
75
	}
76
	
77
	IEnumerator StoreLocalMovement()
78
	{
79
		while(true)
80
		{
81
			yield return new WaitForSeconds(1/10);
82
			
83
			//shift buffer content
84
			for(int i = clientStateBuffer.Length - 1; i >= 1; i--)
85
			{
86
				clientStateBuffer[i] = clientStateBuffer[i - 1];	
87
			}
88
			
89
			clientStateBuffer[0] = new NetState((float)uLink.Network.time, transform.position, transform.rotation);
90
			
91
			m_LocalStateCount = Mathf.Min(m_LocalStateCount + 1, clientStateBuffer.Length);
92
			
93
			//
94
			//Check if the client side prediction has an error
95
			//
96
			
97
			//Find the local buffered state which is closest to network state in time
98
			int j = 0;
99
			bool match = false;
100
			for(j = 0; j < m_LocalStateCount - 1; j++)
101
			{
102
				if(serverStateBuffer[0] != null)
103
				{
104
					if(serverStateBuffer[0].timeStamp <= clientStateBuffer[j].timeStamp && clientStateBuffer[j].timeStamp - serverStateBuffer[0].timeStamp <= m_TimeThreshold)
105
					{
106
						if(Debug.isDebugBuild)
107
						{
108
							Debug.Log("Comparing state " + j + "localtime: " + clientStateBuffer[j].timeStamp  + " networktime: " + serverStateBuffer[0].timeStamp);
109
	                    	Debug.Log("Local: " + clientStateBuffer[j].pos + " Network: " + serverStateBuffer[0].pos);
110
						}
111
						
112
						//m_TimeAccuracy = Mathf.Abs(clientStateBuffer[j].timeStamp - serverStateBuffer[0].timeStamp);
113
						m_PredictionAccuracy = (Vector3.Distance(clientStateBuffer[j].pos, serverStateBuffer[0].pos));
114-
							//Debug.Log("Comparing state " + j + "localtime: " + clientStateBuffer[j].timeStamp  + " networktime: " + serverStateBuffer[0].timeStamp);
114+
115-
	                    	//Debug.Log("Local: " + clientStateBuffer[j].pos + " Network: " + serverStateBuffer[0].pos);
115+
116
					}
117
				}
118
			}
119
			
120
			if(!match)
121
			{
122
				//Debug.log("Not match");	
123
			}
124
			else if(m_PredictionAccuracy > m_PredictionThreshold) //if prediction is off, diverge current location by the amount of the offset
125
			{
126
				if(Debug.isDebugBuild) Debug.Log("PredictionAccuracy sup to Predictionthreshold");
127
				
128
				//Find how fat we travelled since the prediction failed
129
				Vector3 localMovement = clientStateBuffer[j].pos - clientStateBuffer[0].pos;
130
				
131
				//"Erase" old value in the local buffer
132
				m_LocalStateCount = 1;
133
				
134
				//New position which we need to converge to in the update loop
135
				m_NewPosition = serverStateBuffer[0].pos;
136
				
137
				m_NewRotation = serverStateBuffer[0].rot;
138
				
139
				//Trigger the new position convergence routine
140
				m_FixError = true;
141
			}
142
			else
143
			{
144
				m_FixError = false;	
145
			}
146
		}
147
	}
148
	
149
	// Update is called once per frame
150
	void Update () 
151
	{	
152
		if(m_FixError)
153
		{
154
			//transform.position = Vector3.Lerp(m_NewPosition, transform.position, difference.magnitude);
155
			Vector3 predictPos = (m_NewPosition/2) + (clientStateBuffer[0].pos/2);
156
			Vector3 difference = predictPos - transform.position;
157
			
158
			
159
			transform.position = Vector3.Lerp(transform.position, predictPos, difference.magnitude);
160
			transform.rotation = Quaternion.Slerp(transform.rotation, m_NewRotation, difference.magnitude);
161
		}
162
		
163
		
164
	}
165
	
166
}