mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
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:
parent
16b4818f9e
commit
71c0d3b2ee
115
Assets/Mirror/Components/NetworkSceneChecker.cs
Normal file
115
Assets/Mirror/Components/NetworkSceneChecker.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Mirror/Components/NetworkSceneChecker.cs.meta
Normal file
11
Assets/Mirror/Components/NetworkSceneChecker.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7fdb599e1359924bad6255660370252
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
16
doc/Components/NetworkSceneChecker.md
Normal file
16
doc/Components/NetworkSceneChecker.md
Normal 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 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.
|
BIN
doc/Components/NetworkSceneChecker.png
Normal file
BIN
doc/Components/NetworkSceneChecker.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
@ -10,6 +10,8 @@
|
||||
href: NetworkManagerHUD.md
|
||||
- name: NetworkProximityChecker
|
||||
href: NetworkProximityChecker.md
|
||||
- name: NetworkSceneChecker
|
||||
href: NetworkSceneChecker.md
|
||||
- name: NetworkRoomManager
|
||||
href: NetworkRoomManager.md
|
||||
- name: NetworkRoomPlayer
|
||||
|
Loading…
Reference in New Issue
Block a user