DistanceInterestManagement.cs 2.9 KB

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