DistanceInterestManagement.cs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // straight forward Vector3.Distance based interest management.
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace Mirror
  5. {
  6. [AddComponentMenu("Network/ Interest Management/ Distance/Distance Interest Management")]
  7. public class DistanceInterestManagement : InterestManagement
  8. {
  9. [Tooltip("The maximum range that objects will be visible at. Add DistanceInterestManagementCustomRange onto NetworkIdentities for custom ranges.")]
  10. public int visRange = 10;
  11. [Tooltip("Rebuild all every 'rebuildInterval' seconds.")]
  12. public float rebuildInterval = 1;
  13. double lastRebuildTime;
  14. // helper function to get vis range for a given object, or default.
  15. int GetVisRange(NetworkIdentity identity)
  16. {
  17. return identity.TryGetComponent(out DistanceInterestManagementCustomRange custom) ? custom.visRange : visRange;
  18. }
  19. [ServerCallback]
  20. public override void Reset()
  21. {
  22. lastRebuildTime = 0D;
  23. }
  24. public override bool OnCheckObserver(NetworkIdentity identity, NetworkConnectionToClient newObserver)
  25. {
  26. int range = GetVisRange(identity);
  27. return Vector3.Distance(identity.transform.position, newObserver.identity.transform.position) < range;
  28. }
  29. public override void OnRebuildObservers(NetworkIdentity identity, HashSet<NetworkConnectionToClient> newObservers)
  30. {
  31. // cache range and .transform because both call GetComponent.
  32. int range = GetVisRange(identity);
  33. Vector3 position = identity.transform.position;
  34. // brute force distance check
  35. // -> only player connections can be observers, so it's enough if we
  36. // go through all connections instead of all spawned identities.
  37. // -> compared to UNET's sphere cast checking, this one is orders of
  38. // magnitude faster. if we have 10k monsters and run a sphere
  39. // cast 10k times, we will see a noticeable lag even with physics
  40. // layers. but checking to every connection is fast.
  41. foreach (NetworkConnectionToClient conn in NetworkServer.connections.Values)
  42. {
  43. // authenticated and joined world with a player?
  44. if (conn != null && conn.isAuthenticated && conn.identity != null)
  45. {
  46. // check distance
  47. if (Vector3.Distance(conn.identity.transform.position, position) < range)
  48. {
  49. newObservers.Add(conn);
  50. }
  51. }
  52. }
  53. }
  54. // internal so we can update from tests
  55. [ServerCallback]
  56. internal void Update()
  57. {
  58. // rebuild all spawned NetworkIdentity's observers every interval
  59. if (NetworkTime.localTime >= lastRebuildTime + rebuildInterval)
  60. {
  61. RebuildAll();
  62. lastRebuildTime = NetworkTime.localTime;
  63. }
  64. }
  65. }
  66. }