NetworkSceneChecker.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.SceneManagement;
  5. namespace Mirror
  6. {
  7. /// <summary>
  8. /// Component that controls visibility of networked objects between scenes.
  9. /// <para>Any object with this component on it will only be visible to other objects in the same scene</para>
  10. /// <para>This would be used when the server has multiple additive subscenes loaded to isolate players to their respective subscenes</para>
  11. /// </summary>
  12. // Deprecated 2021-02-17
  13. [Obsolete(NetworkVisibilityObsoleteMessage.Message)]
  14. [DisallowMultipleComponent]
  15. [AddComponentMenu("Network/NetworkSceneChecker")]
  16. [RequireComponent(typeof(NetworkIdentity))]
  17. [HelpURL("https://mirror-networking.gitbook.io/docs/components/network-scene-checker")]
  18. public class NetworkSceneChecker : NetworkVisibility
  19. {
  20. /// <summary>
  21. /// Flag to force this object to be hidden from all observers.
  22. /// <para>If this object is a player object, it will not be hidden for that client.</para>
  23. /// </summary>
  24. [Tooltip("Enable to force this object to be hidden from all observers.")]
  25. public bool forceHidden;
  26. // Use Scene instead of string scene.name because when additively loading multiples of a subscene the name won't be unique
  27. static readonly Dictionary<Scene, HashSet<NetworkIdentity>> sceneCheckerObjects = new Dictionary<Scene, HashSet<NetworkIdentity>>();
  28. Scene currentScene;
  29. [ServerCallback]
  30. void Awake()
  31. {
  32. currentScene = gameObject.scene;
  33. // Debug.Log($"NetworkSceneChecker.Awake currentScene: {currentScene}");
  34. }
  35. public override void OnStartServer()
  36. {
  37. if (!sceneCheckerObjects.ContainsKey(currentScene))
  38. sceneCheckerObjects.Add(currentScene, new HashSet<NetworkIdentity>());
  39. sceneCheckerObjects[currentScene].Add(netIdentity);
  40. }
  41. public override void OnStopServer()
  42. {
  43. if (sceneCheckerObjects.ContainsKey(currentScene) && sceneCheckerObjects[currentScene].Remove(netIdentity))
  44. RebuildSceneObservers();
  45. }
  46. [ServerCallback]
  47. void Update()
  48. {
  49. if (currentScene == gameObject.scene)
  50. return;
  51. // This object is in a new scene so observers in the prior scene
  52. // and the new scene need to rebuild their respective observers lists.
  53. // Remove this object from the hashset of the scene it just left
  54. sceneCheckerObjects[currentScene].Remove(netIdentity);
  55. // RebuildObservers of all NetworkIdentity's in the scene this object just left
  56. RebuildSceneObservers();
  57. // Set this to the new scene this object just entered
  58. currentScene = gameObject.scene;
  59. // Make sure this new scene is in the dictionary
  60. if (!sceneCheckerObjects.ContainsKey(currentScene))
  61. sceneCheckerObjects.Add(currentScene, new HashSet<NetworkIdentity>());
  62. // Add this object to the hashset of the new scene
  63. sceneCheckerObjects[currentScene].Add(netIdentity);
  64. // RebuildObservers of all NetworkIdentity's in the scene this object just entered
  65. RebuildSceneObservers();
  66. }
  67. void RebuildSceneObservers()
  68. {
  69. foreach (NetworkIdentity networkIdentity in sceneCheckerObjects[currentScene])
  70. if (networkIdentity != null)
  71. networkIdentity.RebuildObservers(false);
  72. }
  73. /// <summary>
  74. /// Callback used by the visibility system to determine if an observer (player) can see this object.
  75. /// <para>If this function returns true, the network connection will be added as an observer.</para>
  76. /// </summary>
  77. /// <param name="conn">Network connection of a player.</param>
  78. /// <returns>True if the player can see this object.</returns>
  79. public override bool OnCheckObserver(NetworkConnection conn)
  80. {
  81. if (forceHidden)
  82. return false;
  83. return conn.identity.gameObject.scene == gameObject.scene;
  84. }
  85. /// <summary>
  86. /// Callback used by the visibility system to (re)construct the set of observers that can see this object.
  87. /// <para>Implementations of this callback should add network connections of players that can see this object to the observers set.</para>
  88. /// </summary>
  89. /// <param name="observers">The new set of observers for this object.</param>
  90. /// <param name="initialize">True if the set of observers is being built for the first time.</param>
  91. public override void OnRebuildObservers(HashSet<NetworkConnection> observers, bool initialize)
  92. {
  93. // If forceHidden then return without adding any observers.
  94. if (forceHidden)
  95. return;
  96. // Add everything in the hashset for this object's current scene
  97. foreach (NetworkIdentity networkIdentity in sceneCheckerObjects[currentScene])
  98. if (networkIdentity != null && networkIdentity.connectionToClient != null)
  99. observers.Add(networkIdentity.connectionToClient);
  100. }
  101. }
  102. }