-
-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Network Scene Checker Component (#1271)
* Create Network Scene Checker Component * Move objects to subscene in client * Remove OnStartClient * Rewritten with static dictionary * Updated doc * renamed image * Replaced image * fixed image name * Changed to short-circuit return in Update * Changed to using string for key since additive scenes may be unloaded * Added null check * Removed commented line * Update Assets/Mirror/Components/NetworkSceneChecker.cs Co-Authored-By: vis2k <info@noobtuts.com> * Moved initializer to declaration * Removed [Scene, SerializeField] Co-authored-by: vis2k <info@noobtuts.com>
- Loading branch information
Showing
5 changed files
with
144 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
using UnityEngine; | ||
using System.Collections.Generic; | ||
using UnityEngine.SceneManagement; | ||
|
||
namespace Mirror | ||
{ | ||
/// <summary> | ||
/// Component that controls visibility of networked objects between scenes. | ||
/// <para>Any object with this component on it will only be visible to other objects in the same scene</para> | ||
/// <para>This would be used when the server has multiple additive subscenes loaded to isolate players to their respective subscenes</para> | ||
/// </summary> | ||
[AddComponentMenu("Network/NetworkSceneChecker")] | ||
[RequireComponent(typeof(NetworkIdentity))] | ||
[HelpURL("https://mirror-networking.com/docs/Components/NetworkSceneChecker.html")] | ||
public class NetworkSceneChecker : NetworkBehaviour | ||
{ | ||
/// <summary> | ||
/// Flag to force this object to be hidden from all observers. | ||
/// <para>If this object is a player object, it will not be hidden for that client.</para> | ||
/// </summary> | ||
[Tooltip("Enable to force this object to be hidden from all observers.")] | ||
public bool forceHidden; | ||
|
||
static Dictionary<string, HashSet<NetworkIdentity>> sceneCheckerObjects = new Dictionary<string, HashSet<NetworkIdentity>>(); | ||
|
||
string currentScene; | ||
|
||
[ServerCallback] | ||
void Awake() | ||
{ | ||
currentScene = gameObject.scene.name; | ||
} | ||
|
||
public override void OnStartServer() | ||
{ | ||
if (!sceneCheckerObjects.ContainsKey(currentScene)) | ||
sceneCheckerObjects.Add(currentScene, new HashSet<NetworkIdentity>()); | ||
|
||
sceneCheckerObjects[currentScene].Add(netIdentity); | ||
} | ||
|
||
[ServerCallback] | ||
void Update() | ||
{ | ||
if (currentScene == gameObject.scene.name) | ||
return; | ||
|
||
// This object is in a new scene so observers in the prior scene | ||
// and the new scene need to rebuild their respective observers lists. | ||
|
||
// Remove this object from the hashset of the scene it just left | ||
sceneCheckerObjects[currentScene].Remove(netIdentity); | ||
|
||
// RebuildObservers of all NetworkIdentity's in the scene this object just left | ||
RebuildSceneObservers(); | ||
|
||
// Set this to the new scene this object just entered | ||
currentScene = gameObject.scene.name; | ||
|
||
// Make sure this new scene is in the dictionary | ||
if (!sceneCheckerObjects.ContainsKey(currentScene)) | ||
sceneCheckerObjects.Add(currentScene, new HashSet<NetworkIdentity>()); | ||
|
||
// Add this object to the hashset of the new scene | ||
sceneCheckerObjects[currentScene].Add(netIdentity); | ||
|
||
// RebuildObservers of all NetworkIdentity's in the scene this object just entered | ||
RebuildSceneObservers(); | ||
} | ||
|
||
void RebuildSceneObservers() | ||
{ | ||
foreach (NetworkIdentity networkIdentity in sceneCheckerObjects[currentScene]) | ||
if (networkIdentity != null) | ||
networkIdentity.RebuildObservers(false); | ||
} | ||
|
||
public override bool OnCheckObserver(NetworkConnection conn) | ||
{ | ||
if (forceHidden) | ||
return false; | ||
|
||
return conn.identity.gameObject.scene == gameObject.scene; | ||
} | ||
|
||
// Always return true when overriding OnRebuildObservers so that | ||
// Mirror knows not to use the built in rebuild method. | ||
public override bool OnRebuildObservers(HashSet<NetworkConnection> observers, bool initialize) | ||
{ | ||
// If forceHidden then return true without adding any observers. | ||
if (forceHidden) | ||
return true; | ||
|
||
// Add everything in the hashset for this object's current scene | ||
foreach (NetworkIdentity networkIdentity in sceneCheckerObjects[currentScene]) | ||
if (networkIdentity != null && networkIdentity.connectionToClient != null) | ||
observers.Add(networkIdentity.connectionToClient); | ||
|
||
return true; | ||
} | ||
|
||
/// <summary> | ||
/// Called when hiding and showing objects on the host. | ||
/// On regular clients, objects simply spawn/despawn. | ||
/// On host, objects need to remain in scene because the host is also the server. | ||
/// In that case, we simply hide/show meshes for the host player. | ||
/// </summary> | ||
/// <param name="visible"></param> | ||
public override void OnSetHostVisibility(bool visible) | ||
{ | ||
foreach (Renderer rend in GetComponentsInChildren<Renderer>()) | ||
rend.enabled = visible; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# NetworkSceneChecker | ||
|
||
The Network Scene Checker component controls the visibility of game objects for network clients, based on which scene they're in. | ||
|
||
![Network Scene Checker component](NetworkSceneChecker.png) | ||
|
||
- **Force Hidden** | ||
Tick this checkbox to hide this object from all players. | ||
|
||
With the Network Scene Checker, a game running on a client doesn’t have information about game objects that are not visible. This has two main benefits: it reduces the amount of data sent across the network, and it makes your game more secure against hacking. | ||
|
||
This component would typically be used when the server has several subscenes loaded and needs to isolate networked objects to the subscene they're in. | ||
|
||
A game object with a Network Scene Checker component must also have a Network Identity component. When you create a Network Scene Checker component on a game object, Mirror also creates a Network Identity component on that game object if it does not already have one. | ||
|
||
Scene objects with a Network Scene Checker component are disabled when they're not in the same scene, and spawned objects are destroyed when they're not in the same scene. |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters