Skip to content

Commit 2cbd8d2

Browse files
author
FirstGearGames
committed
1.1.1
- Fixed prediction not working when a RPC/SyncType used the same type as prediction. - Fixed data sometimes bundling into other ticks causing the transport to exceed MTU. - Fixed PredictedRigidbody stalling. - Added Warning to PredictedRigidbody inspector. - Improved XML for FrameRate and MaximumClientMTU. - Changed sealed ClientManager, ServerManager, TimeManager, Observermanager, NetworkObject, NetworkManager, NetworkObserver. - Fixed IsNetworked not being set true for client spawns. - Improved internally ServerManager.MaximumClientMTU. - Changed channels count is now hard-coded at 2, for reliable and unreliable. - Obsoleted GetChannelCount() from Transport. Will be removed 2022/06/01.
1 parent 1be07a6 commit 2cbd8d2

File tree

9 files changed

+125
-103
lines changed

9 files changed

+125
-103
lines changed

Assets/FishNet/CodeGenerating/Helpers/GeneralHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ internal class GeneralHelper
2424
internal MethodReference Queue_Clear_MethodRef;
2525
internal TypeReference List_TypeRef;
2626
internal MethodReference List_Clear_MethodRef;
27-
internal MethodReference List_GetItem_MethodRef;
27+
internal MethodReference List_get_Item_MethodRef;
2828
internal MethodReference List_get_Count_MethodRef;
2929
internal MethodReference List_Add_MethodRef;
3030
internal MethodReference List_RemoveRange_MethodRef;
@@ -127,7 +127,7 @@ internal bool ImportReferences()
127127
lstMi = tmpType.GetMethod("get_Count");
128128
List_get_Count_MethodRef = CodegenSession.ImportReference(lstMi);
129129
lstMi = tmpType.GetMethod("get_Item");
130-
List_GetItem_MethodRef = CodegenSession.ImportReference(lstMi);
130+
List_get_Item_MethodRef = CodegenSession.ImportReference(lstMi);
131131
lstMi = tmpType.GetMethod("Clear");
132132
List_Clear_MethodRef = CodegenSession.ImportReference(lstMi);
133133

Assets/FishNet/CodeGenerating/Processing/NetworkBehaviourPredictionProcessor.cs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,6 @@ private bool ProcessLocal(TypeDefinition typeDef, ref uint rpcCount)
345345
CodegenSession.LogError($"Reconcile data type {reconcileDataTd.Name} does not support serialization. Use a supported type or create a custom serializer.");
346346
return false;
347347
}
348-
349348
//Creates fields for buffers.
350349
CreatedPredictionFields predictionFields;
351350
CreateFields(typeDef, replicateMd, reconcileMd, out predictionFields);
@@ -967,12 +966,6 @@ private bool ServerCreateReplicateReader(TypeDefinition typeDef, MethodDefinitio
967966
processor.Emit(OpCodes.Ldfld, predictionFields.ServerReplicateReaderBuffer);
968967
processor.Emit(OpCodes.Stloc, replicateDataArrVd);
969968

970-
// lastTick = _serverReceivedTick;
971-
VariableDefinition lastTickVd = CodegenSession.GeneralHelper.CreateVariable(createdMd, typeof(uint));
972-
processor.Emit(OpCodes.Ldarg_0);
973-
processor.Emit(OpCodes.Ldfld, predictionFields.ServerReceivedTick);
974-
processor.Emit(OpCodes.Stloc, lastTickVd);
975-
976969
/* Store queue count into queueCount. */
977970
//START //Method references for uint get_Count.
978971
GenericInstanceType queueDataGit;
@@ -986,9 +979,11 @@ private bool ServerCreateReplicateReader(TypeDefinition typeDef, MethodDefinitio
986979
// for (int i = 0; i < dataArr.Length; i++)
987980
// {
988981
// Data d = dataArr[i];
989-
// if (d.Tick > lastTick)
982+
// if (d.Tick > this.lastTick)
990983
// _serverReplicateDatas.Add(d);
984+
// this.lastTick = d.Tick;
991985
// }
986+
992987
VariableDefinition iteratorVd = CodegenSession.GeneralHelper.CreateVariable(createdMd, typeof(int));
993988
Instruction iteratorComparerInst = processor.Create(OpCodes.Ldloc, iteratorVd);
994989
Instruction iteratorLogicInst = processor.Create(OpCodes.Nop);
@@ -999,12 +994,18 @@ private bool ServerCreateReplicateReader(TypeDefinition typeDef, MethodDefinitio
999994
processor.Emit(OpCodes.Br_S, iteratorComparerInst);
1000995
//Logic.
1001996
processor.Append(iteratorLogicInst);
997+
998+
//Store the data tick.
999+
VariableDefinition dataTickVd = CodegenSession.GeneralHelper.CreateVariable(createdMd, typeof(int));
10021000
processor.Emit(OpCodes.Ldloc, replicateDataArrVd);
10031001
processor.Emit(OpCodes.Ldloc, iteratorVd);
10041002
processor.Emit(OpCodes.Ldelema, replicateDataTr);
10051003
processor.Emit(OpCodes.Ldfld, ReplicateData_Tick_FieldRef);
1006-
//processor.Emit(OpCodes.Conv_U8);
1007-
processor.Emit(OpCodes.Ldloc, lastTickVd);
1004+
processor.Emit(OpCodes.Stloc, dataTickVd);
1005+
1006+
processor.Emit(OpCodes.Ldloc, dataTickVd);
1007+
processor.Emit(OpCodes.Ldarg_0);
1008+
processor.Emit(OpCodes.Ldfld, predictionFields.ServerReceivedTick);
10081009
processor.Emit(OpCodes.Ble_S, iteratorIncreaseComparerInst);
10091010
//Add to buffer.
10101011
processor.Emit(OpCodes.Ldarg_0);
@@ -1016,10 +1017,7 @@ private bool ServerCreateReplicateReader(TypeDefinition typeDef, MethodDefinitio
10161017

10171018
//Set serverReceivedTick.
10181019
processor.Emit(OpCodes.Ldarg_0);
1019-
processor.Emit(OpCodes.Ldloc, replicateDataArrVd);
1020-
processor.Emit(OpCodes.Ldloc, iteratorVd);
1021-
processor.Emit(OpCodes.Ldelema, replicateDataTr);
1022-
processor.Emit(OpCodes.Ldfld, ReplicateData_Tick_FieldRef);
1020+
processor.Emit(OpCodes.Ldloc, dataTickVd);
10231021
processor.Emit(OpCodes.Stfld, predictionFields.ServerReceivedTick);
10241022
// ; i++)
10251023
processor.Append(iteratorIncreaseComparerInst); //(OpCodes.Ldloc, iteratorVd);
@@ -1295,7 +1293,7 @@ private void ClientSetReplicateDataTick(MethodDefinition methodDef, ParameterDef
12951293
OpCode ldArgOC = (dataPd.ParameterType.IsValueType) ? OpCodes.Ldarga : OpCodes.Ldarg;
12961294
processor.Emit(ldArgOC, dataPd);
12971295
processor.Emit(OpCodes.Ldloc, tickVd);
1298-
processor.Emit(OpCodes.Stfld, ReplicateData_Tick_FieldRef.CachedResolve());
1296+
processor.Emit(OpCodes.Stfld, ReplicateData_Tick_FieldRef.CachedResolve());
12991297
}
13001298
/// <summary>
13011299
/// Sends clients inputs to server.
@@ -1456,7 +1454,7 @@ private void ClientRemoveFromCache(MethodDefinition reconcileMd, MethodDefinitio
14561454
GenericInstanceType lstDataGit;
14571455
GetGenericLists(replicateDataTr, out lstDataGit);
14581456
MethodReference replicateGetCountMr = CodegenSession.GeneralHelper.List_get_Count_MethodRef.MakeHostInstanceGeneric(lstDataGit);
1459-
MethodReference replicateGetItemMr = CodegenSession.GeneralHelper.List_GetItem_MethodRef.MakeHostInstanceGeneric(lstDataGit);
1457+
MethodReference replicateGetItemMr = CodegenSession.GeneralHelper.List_get_Item_MethodRef.MakeHostInstanceGeneric(lstDataGit);
14601458
MethodReference replicateClearMr = CodegenSession.GeneralHelper.List_Clear_MethodRef.MakeHostInstanceGeneric(lstDataGit);
14611459

14621460
Instruction iteratorIncreaseInst = processor.Create(OpCodes.Ldloc, iteratorVd);
@@ -1553,7 +1551,7 @@ private void ClientReplayBuffered(MethodDefinition reconcileMd, MethodDefinition
15531551
GenericInstanceType lstDataGit;
15541552
GetGenericLists(replicateDataTr, out lstDataGit);
15551553
MethodReference dataCollectionGetCountMr = CodegenSession.GeneralHelper.List_get_Count_MethodRef.MakeHostInstanceGeneric(lstDataGit);
1556-
MethodReference dataCollectionGetItemMr = CodegenSession.GeneralHelper.List_GetItem_MethodRef.MakeHostInstanceGeneric(lstDataGit);
1554+
MethodReference dataCollectionGetItemMr = CodegenSession.GeneralHelper.List_get_Item_MethodRef.MakeHostInstanceGeneric(lstDataGit);
15571555

15581556
Instruction iteratorComparerInst = processor.Create(OpCodes.Ldloc, iteratorVd);
15591557
Instruction iteratorLogicInst = processor.Create(OpCodes.Nop);

Assets/FishNet/CodeGenerating/Processing/NetworkBehaviourProcessor.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,24 @@ internal bool Process(TypeDefinition typeDef, List<(SyncType, ProcessedSync)> al
7373
/* Create NetworkInitialize before-hand so the other procesors
7474
* can use it. */
7575
CreateNetworkInitializeMethods(copyTypeDef);
76+
77+
uint rpcCount = 0;
78+
/* Prediction. */
79+
/* Run prediction first since prediction will modify
80+
* user data passed into prediction methods. Because of this
81+
* other RPCs should use the modified version and reader/writers
82+
* made for prediction. */
83+
modified |= CodegenSession.NetworkBehaviourPredictionProcessor.Process(copyTypeDef, ref rpcCount);
84+
//25ms
85+
7686
/* RPCs. */
77-
uint rpcCount;
7887
childRpcCounts.TryGetValue(copyTypeDef, out rpcCount);
7988
modified |= CodegenSession.NetworkBehaviourRpcProcessor.Process(copyTypeDef, ref rpcCount);
8089
//30ms
8190
/* //perf rpcCounts can be optimized by having different counts
8291
* for target, observers, server, replicate, and reoncile rpcs. Since
8392
* each registers to their own delegates this is possible. */
8493

85-
/* Prediction. */
86-
modified |= CodegenSession.NetworkBehaviourPredictionProcessor.Process(copyTypeDef, ref rpcCount);
87-
//25ms
88-
8994
/* SyncTypes. */
9095
uint syncTypeStartCount;
9196
childSyncTypeCounts.TryGetValue(copyTypeDef, out syncTypeStartCount);

Assets/FishNet/Runtime/Generated/Component/Prediction/PredictedRigidbody.cs

Lines changed: 56 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ private void TimeManager_OnPostTick()
120120
SendRigidbodyState();
121121
}
122122
}
123-
else if (base.IsClient)
123+
124+
if (CanPredict())
124125
{
125126
_predictedTicks++;
126127
PredictVelocity(gameObject.scene.GetPhysicsScene());
@@ -139,22 +140,34 @@ private void InitializeOnce()
139140

140141
private void TimeManager_OnPreReconcile(NetworkBehaviour obj)
141142
{
142-
if (base.IsOwner)
143+
if (!CanPredict())
143144
return;
144145

145146
_physicsScene = gameObject.scene.GetPhysicsScene();
146147
if (_physicsScene == obj.gameObject.scene.GetPhysicsScene())
147148
ResetRigidbodyToData();
148149
}
149150

151+
/// <summary>
152+
/// Returns if prediction can be used on this rigidbody.
153+
/// </summary>
154+
/// <returns></returns>
155+
private bool CanPredict()
156+
{
157+
if (base.IsServer || base.IsOwner || _predictionRatio <= 0f)
158+
return false;
159+
160+
return true;
161+
}
150162

151163
/// <summary>
152164
/// Called before physics is simulated when replaying a replicate method.
153165
/// Contains the PhysicsScene and PhysicsScene2D which was simulated.
154166
/// </summary>
155167
private void TimeManager_OnPostReplicateReplay(PhysicsScene ps, PhysicsScene2D ps2d)
156168
{
157-
PredictVelocity(ps);
169+
if (CanPredict())
170+
PredictVelocity(ps);
158171
}
159172

160173
/// <summary>
@@ -182,68 +195,62 @@ private void ResetRigidbodyToData()
182195
/// </summary>
183196
private void PredictVelocity(PhysicsScene ps)
184197
{
185-
if (_predictionRatio == 0f)
186-
return;
187-
if (base.IsOwner)
188-
return;
189-
if (base.IsServer)
190-
return;
191198
if (ps != _physicsScene)
192199
return;
193200

194201
PredictVelocity(ref _velocityBaseline, ref _lastVelocity, _rigidbody.velocity, false);
195202
PredictVelocity(ref _angularVelocityBaseline, ref _lastAngularVelocity, _rigidbody.angularVelocity, true);
196203

197-
_lastVelocity = _rigidbody.velocity;
198-
_lastAngularVelocity = _rigidbody.angularVelocity;
199-
}
200-
201-
/// <summary>
202-
/// Tries to predict velocity.
203-
/// </summary>
204-
private void PredictVelocity(ref float? velocityBaseline, ref Vector3 lastVelocity, Vector3 velocity, bool angular)
205-
{
206-
float velocityDifference;
207-
float directionDifference;
208-
209-
/* Velocity. */
210-
directionDifference = (velocityBaseline != null) ?
211-
Vector3.SqrMagnitude(lastVelocity.normalized - velocity.normalized) :
212-
0f;
213-
//If direction has changed too much then reset the baseline.
214-
if (directionDifference > 0.01f)
215-
{
216-
velocityBaseline = null;
217-
}
218-
//Direction hasn't changed enough to reset baseline.
219-
else
204+
/// <summary>
205+
/// Tries to predict velocity.
206+
/// </summary>
207+
void PredictVelocity(ref float? velocityBaseline, ref Vector3 lastVelocity, Vector3 velocity, bool angular)
220208
{
221-
//Difference in velocity since last simulation.
222-
velocityDifference = Vector3.Magnitude(lastVelocity - velocity);
223-
//If there is no baseline.
224-
if (velocityBaseline == null)
209+
float velocityDifference;
210+
float directionDifference;
211+
212+
/* Velocity. */
213+
directionDifference = (velocityBaseline != null) ?
214+
Vector3.SqrMagnitude(lastVelocity.normalized - velocity.normalized) :
215+
0f;
216+
//If direction has changed too much then reset the baseline.
217+
if (directionDifference > 0.01f)
225218
{
226-
if (velocityDifference > 0)
227-
velocityBaseline = velocityDifference;
219+
velocityBaseline = null;
228220
}
229-
//If there is a baseline.
221+
//Direction hasn't changed enough to reset baseline.
230222
else
231223
{
232-
//If the difference exceeds the baseline by 10% then reset baseline so another will be calculated.
233-
if (velocityDifference > (velocityBaseline.Value * 1.1f) || velocityDifference < (velocityBaseline.Value * 0.9f))
224+
//Difference in velocity since last simulation.
225+
velocityDifference = Vector3.Magnitude(lastVelocity - velocity);
226+
//If there is no baseline.
227+
if (velocityBaseline == null)
234228
{
235-
velocityBaseline = null;
229+
if (velocityDifference > 0)
230+
velocityBaseline = velocityDifference;
236231
}
237-
//Velocity difference is close enough to the baseline to where it doesn't need to be reset, so use prediction.
232+
//If there is a baseline.
238233
else
239234
{
240-
if (!angular)
241-
_rigidbody.velocity = Vector3.Lerp(velocity, lastVelocity, _predictionRatio);
235+
//If the difference exceeds the baseline by 10% then reset baseline so another will be calculated.
236+
if (velocityDifference > (velocityBaseline.Value * 1.1f) || velocityDifference < (velocityBaseline.Value * 0.9f))
237+
{
238+
velocityBaseline = null;
239+
}
240+
//Velocity difference is close enough to the baseline to where it doesn't need to be reset, so use prediction.
242241
else
243-
_rigidbody.angularVelocity = Vector3.Lerp(velocity, lastVelocity, _predictionRatio);
242+
{
243+
if (!angular)
244+
_rigidbody.velocity = Vector3.Lerp(velocity, lastVelocity, _predictionRatio);
245+
else
246+
_rigidbody.angularVelocity = Vector3.Lerp(velocity, lastVelocity, _predictionRatio);
247+
}
244248
}
245249
}
246250
}
251+
252+
_lastVelocity = _rigidbody.velocity;
253+
_lastAngularVelocity = _rigidbody.angularVelocity;
247254
}
248255

249256

@@ -270,6 +277,9 @@ private void SendRigidbodyState()
270277
[ObserversRpc(IncludeOwner = false, BufferLast = true)]
271278
private void ObserversSendRigidbodyState(RigidbodyState state, Channel channel = Channel.Unreliable)
272279
{
280+
if (!CanPredict())
281+
return;
282+
273283
_receivedRigidbodyState = state;
274284
ResetRigidbodyToData();
275285
PhysicsScene ps = gameObject.scene.GetPhysicsScene();

0 commit comments

Comments
 (0)