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>
This commit is contained in:
MrGadget 2020-01-25 15:48:47 -05:00 committed by GitHub
parent 16b4818f9e
commit 71c0d3b2ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 144 additions and 0 deletions

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b7fdb599e1359924bad6255660370252
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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 doesnt 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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -10,6 +10,8 @@
href: NetworkManagerHUD.md
- name: NetworkProximityChecker
href: NetworkProximityChecker.md
- name: NetworkSceneChecker
href: NetworkSceneChecker.md
- name: NetworkRoomManager
href: NetworkRoomManager.md
- name: NetworkRoomPlayer