BufferedState
How do I use Buffered State
Below are practical examples compiled from projects for learning and reference purposes
Featured Snippets
Line | Code | Ex.. |
---|---|---|
54 | for (int i = m_BufferedState.Length - 1; i >= 1; i--) | 1 |
91 | if (m_BufferedState[0].timestamp > interpolationTime) | 2 |
File name: CubeInter.cs
Copy
34 void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
35 {
36 // Always send transform (depending on reliability of the network view)
37 if (stream.isWriting)
38 {
39 Vector3 pos = transform.localPosition;
40 Quaternion rot = transform.localRotation;
41 stream.Serialize(ref pos);
42 stream.Serialize(ref rot);
43 }
44 // When receiving, buffer the information
45 else
46 {
47 // Receive latest state information
48 Vector3 pos = Vector3.zero;
49 Quaternion rot = Quaternion.identity;
50 stream.Serialize(ref pos);
51 stream.Serialize(ref rot);
52
53 // Shift buffer contents, oldest data erased, 18 becomes 19, ... , 0 becomes 1
54 for (int i = m_BufferedState.Length - 1; i >= 1; i--)
55 {
56 m_BufferedState[i] = m_BufferedState[i - 1];
57 }
58
59
60 // Save currect received state as 0 in the buffer, safe to overwrite after shifting
61 State state;
62 state.timestamp = info.timestamp;
63 state.pos = pos;
64 state.rot = rot;
65 m_BufferedState[0] = state;
66
67 // Increment state count but never exceed buffer size
68 m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.Length);
69
70 // Check integrity, lowest numbered state in the buffer is newest and so on
71 for (int i = 0; i < m_TimestampCount - 1; i++)
72 {
73 if (m_BufferedState[i].timestamp < m_BufferedState[i + 1].timestamp)
74 Debug.Log("State inconsistent");
75 }
76 }
77 }
File name: CubeInter.cs
Copy
79 // This only runs where the component is enabled, which is only on remote peers (server/clients)
80 void Update()
81 {
82 double currentTime = PhotonNetwork.time;
83 double interpolationTime = currentTime - interpolationBackTime;
84 // We have a window of interpolationBackTime where we basically play
85 // By having interpolationBackTime the average ping, you will usually use interpolation.
86 // And only if no more data arrives we will use extrapolation
87
88 // Use interpolation
89 // Check if latest state exceeds interpolation time, if this is the case then
90 // it is too old and extrapolation should be used
91 if (m_BufferedState[0].timestamp > interpolationTime)
92 {
93 for (int i = 0; i < m_TimestampCount; i++)
94 {
95 // Find the state which matches the interpolation time (time+0.1) or use last state
96 if (m_BufferedState[i].timestamp <= interpolationTime || i == m_TimestampCount - 1)
97 {
98 // The state one slot newer (<100ms) than the best playback state
99 State rhs = m_BufferedState[Mathf.Max(i - 1, 0)];
100 // The best playback state (closest to 100 ms old (default time))
101 State lhs = m_BufferedState[i];
102
103 // Use the time between the two slots to determine if interpolation is necessary
104 double length = rhs.timestamp - lhs.timestamp;
105 float t = 0.0F;
106 // As the time difference gets closer to 100 ms t gets closer to 1 in
107 // which case rhs is only used
108 if (length > 0.0001)
109 t = (float)((interpolationTime - lhs.timestamp) / length);
110
111 // if t=0 => lhs is used directly
112 transform.localPosition = Vector3.Lerp(lhs.pos, rhs.pos, t);
113 transform.localRotation = Quaternion.Slerp(lhs.rot, rhs.rot, t);
114 return;
115 }
116 }
117 }
118 // Use extrapolation. Here we do something really simple and just repeat the last
119 // received state. You can do clever stuff with predicting what should happen.
120 else
121 {
122 State latest = m_BufferedState[0];
123
124 transform.localPosition = Vector3.Lerp(transform.localPosition, latest.pos, Time.deltaTime * 20 );
125 transform.localRotation = latest.rot;
126 }
127 }
BufferedState 99 lượt xem
Gõ tìm kiếm nhanh...