|
13 | 13 | using MLAPI.Serialization;
|
14 | 14 | using MLAPI.Serialization.Pooled;
|
15 | 15 | using MLAPI.Transports;
|
| 16 | +using Unity.Profiling; |
16 | 17 |
|
17 | 18 | namespace MLAPI
|
18 | 19 | {
|
@@ -296,6 +297,11 @@ protected NetworkBehaviour GetNetworkBehaviour(ushort behaviourId)
|
296 | 297 | /// </summary>
|
297 | 298 | public ulong OwnerClientId => NetworkObject.OwnerClientId;
|
298 | 299 |
|
| 300 | + /// <summary> |
| 301 | + /// Stores the network tick at the NetworkBehaviourUpdate time |
| 302 | + /// This allows sending NetworkVariables not more often than once per network tick, regardless of the update rate |
| 303 | + /// </summary> |
| 304 | + public static ushort CurrentTick { get; private set; } |
299 | 305 |
|
300 | 306 | /// <summary>
|
301 | 307 | /// Gets called when message handlers are ready to be registered and the network is setup
|
@@ -347,6 +353,7 @@ public virtual void OnNetworkObjectParentChanged(NetworkObject parentNetworkObje
|
347 | 353 | private readonly List<NetworkChannel> m_ChannelsForNetworkVariableGroups = new List<NetworkChannel>();
|
348 | 354 | internal readonly List<INetworkVariable> NetworkVariableFields = new List<INetworkVariable>();
|
349 | 355 |
|
| 356 | + private static HashSet<NetworkObject> s_Touched = new HashSet<NetworkObject>(); |
350 | 357 | private static Dictionary<Type, FieldInfo[]> s_FieldTypes = new Dictionary<Type, FieldInfo[]>();
|
351 | 358 |
|
352 | 359 | private static FieldInfo[] GetFieldInfoForType(Type type)
|
@@ -439,6 +446,83 @@ internal void InitializeVariables()
|
439 | 446 | }
|
440 | 447 | }
|
441 | 448 |
|
| 449 | +#if DEVELOPMENT_BUILD || UNITY_EDITOR |
| 450 | + private static ProfilerMarker s_NetworkBehaviourUpdate = new ProfilerMarker($"{nameof(NetworkBehaviour)}.{nameof(NetworkBehaviourUpdate)}"); |
| 451 | +#endif |
| 452 | + |
| 453 | + internal static void NetworkBehaviourUpdate(NetworkManager networkManager) |
| 454 | + { |
| 455 | + // Do not execute NetworkBehaviourUpdate more than once per network tick |
| 456 | + ushort tick = networkManager.NetworkTickSystem.GetTick(); |
| 457 | + if (tick == CurrentTick) |
| 458 | + { |
| 459 | + return; |
| 460 | + } |
| 461 | + |
| 462 | + CurrentTick = tick; |
| 463 | + |
| 464 | +#if DEVELOPMENT_BUILD || UNITY_EDITOR |
| 465 | + s_NetworkBehaviourUpdate.Begin(); |
| 466 | +#endif |
| 467 | + try |
| 468 | + { |
| 469 | + if (networkManager.IsServer) |
| 470 | + { |
| 471 | + s_Touched.Clear(); |
| 472 | + for (int i = 0; i < networkManager.ConnectedClientsList.Count; i++) |
| 473 | + { |
| 474 | + var client = networkManager.ConnectedClientsList[i]; |
| 475 | + var spawnedObjs = networkManager.SpawnManager.SpawnedObjectsList; |
| 476 | + s_Touched.UnionWith(spawnedObjs); |
| 477 | + foreach (var sobj in spawnedObjs) |
| 478 | + { |
| 479 | + // Sync just the variables for just the objects this client sees |
| 480 | + for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++) |
| 481 | + { |
| 482 | + sobj.ChildNetworkBehaviours[k].VariableUpdate(client.ClientId); |
| 483 | + } |
| 484 | + } |
| 485 | + } |
| 486 | + |
| 487 | + // Now, reset all the no-longer-dirty variables |
| 488 | + foreach (var sobj in s_Touched) |
| 489 | + { |
| 490 | + for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++) |
| 491 | + { |
| 492 | + sobj.ChildNetworkBehaviours[k].PostNetworkVariableWrite(); |
| 493 | + } |
| 494 | + } |
| 495 | + } |
| 496 | + else |
| 497 | + { |
| 498 | + // when client updates the sever, it tells it about all its objects |
| 499 | + foreach (var sobj in networkManager.SpawnManager.SpawnedObjectsList) |
| 500 | + { |
| 501 | + for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++) |
| 502 | + { |
| 503 | + sobj.ChildNetworkBehaviours[k].VariableUpdate(networkManager.ServerClientId); |
| 504 | + } |
| 505 | + } |
| 506 | + |
| 507 | + // Now, reset all the no-longer-dirty variables |
| 508 | + foreach (var sobj in networkManager.SpawnManager.SpawnedObjectsList) |
| 509 | + { |
| 510 | + for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++) |
| 511 | + { |
| 512 | + sobj.ChildNetworkBehaviours[k].PostNetworkVariableWrite(); |
| 513 | + } |
| 514 | + } |
| 515 | + } |
| 516 | + } |
| 517 | + finally |
| 518 | + { |
| 519 | +#if DEVELOPMENT_BUILD || UNITY_EDITOR |
| 520 | + s_NetworkBehaviourUpdate.End(); |
| 521 | +#endif |
| 522 | + } |
| 523 | + } |
| 524 | + |
| 525 | + |
442 | 526 | internal void PreNetworkVariableWrite()
|
443 | 527 | {
|
444 | 528 | // reset our "which variables got written" data
|
|
0 commit comments