mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
Replaced excessive use of 'GameObject' with 'game object' in docs
This commit is contained in:
parent
7348ab3ecd
commit
a20d9a1795
@ -2,7 +2,7 @@
|
||||
|
||||
The Network Animator component allows you to synchronize animation states for networked objects. It synchronizes state and parameters from an Animator Controller.
|
||||
|
||||
Note that if you create a Network Animator component on an empty GameObject, Mirror also creates a Network Identity component and an Animator component on that GameObject.
|
||||
Note that if you create a Network Animator component on an empty game object, Mirror also creates a Network Identity component and an Animator component on that game object.
|
||||
|
||||
![The Network Animator component in the Inspector window](NetworkAnimatorComponent.png)
|
||||
|
||||
@ -11,8 +11,8 @@ Note that if you create a Network Animator component on an empty GameObject, Mir
|
||||
|
||||
## Details
|
||||
|
||||
The Network Animator ensures the synchronization of GameObject animation across the network - meaning that all players see the animation happen at the same. There are two kinds of authority for networked animation (see documentation on Network system concepts for more information about authority)):
|
||||
The Network Animator ensures the synchronization of game object animation across the network - meaning that all players see the animation happen at the same. There are two kinds of authority for networked animation (see documentation on Network system concepts for more information about authority)):
|
||||
|
||||
- If the GameObject has authority on the client, you should animate it locally on the client that owns the GameObject. That client sends the animation state information to the server, which broadcasts it to all the other clients. For example, this may be suitable for player characters with client authority.
|
||||
- If the GameObject has authority on the server, then you should animate it on the server. The server then sends state information to all clients. This is common for animated GameObjects that are not related to a specific client, such as scene objects and non-player characters, or server-authoritative clients.
|
||||
- Animator Triggers are not synced directly. Call `NetworkAdnimator.SetTrigger` instead. A GameObject with authority can use the SetTrigger function to fire an animation trigger on other clients.
|
||||
- If the game object has authority on the client, you should animate it locally on the client that owns the game object. That client sends the animation state information to the server, which broadcasts it to all the other clients. For example, this may be suitable for player characters with client authority.
|
||||
- If the game object has authority on the server, then you should animate it on the server. The server then sends state information to all clients. This is common for animated game objects that are not related to a specific client, such as scene objects and non-player characters, or server-authoritative clients.
|
||||
- Animator Triggers are not synced directly. Call `NetworkAdnimator.SetTrigger` instead. A game object with authority can use the SetTrigger function to fire an animation trigger on other clients.
|
||||
|
@ -1,27 +1,27 @@
|
||||
# NetworkIdentity
|
||||
|
||||
The Network Identity component is at the heart of the Unity networking high-level API. It controls a GameObject’s unique identity on the network, and it uses that identity to make the networking system aware of the GameObject. It offers two different options for configuration and they are mutually exclusive, which means either one of the options or none can be checked.
|
||||
The Network Identity component is at the heart of the Unity networking high-level API. It controls a game object’s unique identity on the network, and it uses that identity to make the networking system aware of the game object. It offers two different options for configuration and they are mutually exclusive, which means either one of the options or none can be checked.
|
||||
|
||||
- **Server Only**
|
||||
Tick this checkbox to ensure that Unity only spawns the GameObject on the server, and not on clients.
|
||||
Tick this checkbox to ensure that Unity only spawns the game object on the server, and not on clients.
|
||||
- **Local Player Authority**
|
||||
Tick this checkbox to give authoritative network control of this GameObject to the client that owns it. The player GameObject on that client has authority over it. Other components such as Network Transform use this to determine which client to treat as the source of authority.
|
||||
Tick this checkbox to give authoritative network control of this game object to the client that owns it. The player game object on that client has authority over it. Other components such as Network Transform use this to determine which client to treat as the source of authority.
|
||||
|
||||
If none of these options is checked, the server will have authority over the object. Changes made by clients (e.g. moving the object) are not allowed and will not be synchronized.
|
||||
|
||||
![Inspector](NetworkIdentity.jpg)
|
||||
|
||||
## Instantiated Network GameObjects
|
||||
## Instantiated Network Game Objects
|
||||
|
||||
With the Unity’s server-authoritative networking system, the server must spawn networked GameObjects with network identities, using `NetworkServer.Spawn`. This automatically creates them on clients that are connected to the server, and assigns them a `netId`.
|
||||
With the Unity’s server-authoritative networking system, the server must spawn networked game objects with network identities, using `NetworkServer.Spawn`. This automatically creates them on clients that are connected to the server, and assigns them a `netId`.
|
||||
|
||||
You must put a Network Identity component on any Prefabs that spawn at runtime for the network system to use them. See [Object Spawning](../Concepts/GameObjects/SpawnObject) for more information.
|
||||
|
||||
## Scene-based Network GameObjects
|
||||
## Scene-based Network Game Objects
|
||||
|
||||
You can also network GameObjects that are saved as part of your Scene (for example, environmental props). Networking GameObjects makes them behave slightly differently, because you need to have them spawn across the network.
|
||||
You can also network game objects that are saved as part of your Scene (for example, environmental props). Networking game objects makes them behave slightly differently, because you need to have them spawn across the network.
|
||||
|
||||
When building your game, Unity disables all Scene-based GameObjects with Network Identity components. When a client connects to the server, the server sends spawn messages to tell the client which Scene GameObjects to enable and what their most up-to-date state information is. This ensures the client’s game does not contain GameObjects at incorrect locations when they start playing, or that Unity does not spawn and immediately destroy GameObjects on connection (for example, if an event removed the GameObject before that client connected). See [Networked Scene GameObjects](../Concepts/GameObjects/SceneObjects) for more information.
|
||||
When building your game, Unity disables all Scene-based game objects with Network Identity components. When a client connects to the server, the server sends spawn messages to tell the client which Scene game objects to enable and what their most up-to-date state information is. This ensures the client’s game does not contain game objects at incorrect locations when they start playing, or that Unity does not spawn and immediately destroy game objects on connection (for example, if an event removed the game object before that client connected). See [Networked Scene Game Objects](../Concepts/GameObjects/SceneObjects) for more information.
|
||||
|
||||
## Preview Pane Information
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
The Network Lobby Player stores per-player state for the [Network Lobby Manager](NetworkLobbyManager) while in the lobby. When using this component, you need to write a script which allows players to indicate they are ready to begin playing, which sets the ReadyToBegin property.
|
||||
|
||||
A GameObject with a Network Lobby Player component must also have a Network Identity component. When you create a Network Lobby Player component on a GameObject, Unity also creates a Network Identity component on that GameObject if it does not already have one.
|
||||
A game object with a Network Lobby Player component must also have a Network Identity component. When you create a Network Lobby Player component on a game object, Unity also creates a Network Identity component on that game object if it does not already have one.
|
||||
|
||||
![Network Lobby Player](NetworkLobbyPlayer.PNG)
|
||||
|
||||
|
@ -11,15 +11,15 @@ General description of Components
|
||||
- [NetworkManagerHUD](NetworkManagerHUD)
|
||||
The Network Manager HUD is a quick-start tool to help you start building your multiplayer game straight away, without first having to build a user interface for game creation/connection/joining. It allows you to jump straight into your gameplay programming, and means you can build your own version of these controls later in your development schedule.
|
||||
- [NetworkIdentity](NetworkIdentity)
|
||||
The Network Identity component is at the heart of the Mirror networking high-level API. It controls a GameObject’s unique identity on the network, and it uses that identity to make the networking system aware of the GameObject. It offers two different options for configuration and they are mutually exclusive, which means either one of the options or none can be checked.
|
||||
The Network Identity component is at the heart of the Mirror networking high-level API. It controls a game object’s unique identity on the network, and it uses that identity to make the networking system aware of the game object. It offers two different options for configuration and they are mutually exclusive, which means either one of the options or none can be checked.
|
||||
- [NetworkStartPosition](NetworkStartPosition)
|
||||
Network Start Position is used by the Network Manager when creating player objects. The position and rotation of the Network Start Position are used to place the newly created player object.
|
||||
- [NetworkProximityChecker](NetworkProximityChecker)
|
||||
The Network Proximity Checker component controls the visibility of GameObjects for network clients, based on proximity to players.
|
||||
The Network Proximity Checker component controls the visibility of game objects for network clients, based on proximity to players.
|
||||
- [NetworkTransform](NetworkTransform)
|
||||
The Network Transform component synchronizes the movement and rotation of GameObjects across the network. Note that the network Transform component only synchronizes spawned networked GameObjects.
|
||||
The Network Transform component synchronizes the movement and rotation of game objects across the network. Note that the network Transform component only synchronizes spawned networked game objects.
|
||||
- [NetworkTransformChild](NetworkTransformChild)
|
||||
The Network Transform Child component synchronizes the position and rotation of the child GameObject of a GameObject with a Network Transform component.
|
||||
The Network Transform Child component synchronizes the position and rotation of the child game object of a game object with a Network Transform component.
|
||||
- [NetworkAnimator](NetworkAnimator)
|
||||
The Network Animator component allows you to synchronize animation states for networked objects. It synchronizes state and parameters from an Animator Controller.
|
||||
- [NetworkNavMeshAgent](NetworkNavMeshAgent)
|
||||
|
@ -1,38 +1,38 @@
|
||||
# Network Authority
|
||||
|
||||
Servers and clients can both manage a GameObject’s behavior. The concept of “authority” refers to how and where a GameObject is managed.
|
||||
Servers and clients can both manage a game object’s behavior. The concept of “authority” refers to how and where a game object is managed.
|
||||
|
||||
## Server Authority
|
||||
|
||||
The default state of authority in networked games using Mirror is that the Server has authority over all GameObjects which do not represent players. This means - for example - the server would manage control of all collectable items, moving platforms, NPCs - and any other parts of your game that players can interac and player GameObjects have authority on their owner’s client (meaning the client manages their behavior).
|
||||
The default state of authority in networked games using Mirror is that the Server has authority over all game objects which do not represent players. This means - for example - the server would manage control of all collectable items, moving platforms, NPCs - and any other parts of your game that players can interac and player game objects have authority on their owner’s client (meaning the client manages their behavior).
|
||||
|
||||
## Local Authority
|
||||
|
||||
Local authority (sometimes referred to as client authority) means the local client has authoritative control over a particular networked GameObject. This is in contrast to the default state which is that the server has authoritative control over networked GameObjects.
|
||||
Local authority (sometimes referred to as client authority) means the local client has authoritative control over a particular networked game object. This is in contrast to the default state which is that the server has authoritative control over networked game objects.
|
||||
|
||||
In addition to `isLocalPlayer`, you can choose to make the player GameObjects have “local authority”. This means that the player GameObject on its owner’s client is responsible for (or has authority over) itself. This is particularly useful for controlling movement; it means that each client has authority over how their own player GameObject is being controlled.
|
||||
In addition to `isLocalPlayer`, you can choose to make the player game objects have “local authority”. This means that the player game object on its owner’s client is responsible for (or has authority over) itself. This is particularly useful for controlling movement; it means that each client has authority over how their own player game object is being controlled.
|
||||
|
||||
To enable local player authority on a GameObject, tick the Network Identity component’s Local Player Authority checkbox. The Network Transform component uses this “authority” setting, and sends movement information from the client to the other clients if this is set.
|
||||
To enable local player authority on a game object, tick the Network Identity component’s Local Player Authority checkbox. The Network Transform component uses this “authority” setting, and sends movement information from the client to the other clients if this is set.
|
||||
|
||||
See Scripting API Reference documentation on NetworkIdentity and localPlayerAuthority for information on implementing local player authority via script.
|
||||
|
||||
![This image shows the Enemy object under server authority. The enemy appears on Client 1 and Client 2, but the server is in charge of its position, movement, and behavior](NetworkAuthority.png)
|
||||
|
||||
Use the NetworkIdentity.hasAuthority property to find out whether a GameObject has local authority (also accessible on `NetworkBehaviour` for convenience). Non-player GameObjects have authority on the server, and player GameObjects with localPlayerAuthority set have authority on their owner’s client.
|
||||
Use the NetworkIdentity.hasAuthority property to find out whether a game object has local authority (also accessible on `NetworkBehaviour` for convenience). Non-player game objects have authority on the server, and player game objects with localPlayerAuthority set have authority on their owner’s client.
|
||||
|
||||
## Local (Client) Authority for Non-Player GameObjects
|
||||
## Local (Client) Authority for Non-Player Game Objects
|
||||
|
||||
It is possible to have client authority over non-player GameObjects. There are two ways to do this. One is to spawn the GameObject using NetworkServer.SpawnWithClientAuthority, and pass the network connection of the client to take ownership. The other is to use NetworkIdentity.AssignClientAuthority with the network connection of the client to take ownership.
|
||||
It is possible to have client authority over non-player game objects. There are two ways to do this. One is to spawn the game object using NetworkServer.SpawnWithClientAuthority, and pass the network connection of the client to take ownership. The other is to use NetworkIdentity.AssignClientAuthority with the network connection of the client to take ownership.
|
||||
|
||||
Assigning authority to a client causes Mirror to call OnStartAuthority() on each `NetworkBehaviour` on the GameObject, and sets the `hasAuthority` property to true. On other clients, the `hasAuthority` property remains false. Non-player GameObjects with client authority can send commands, just like players can. These commands are run on the server instance of the GameObject, not on the player associated with the connection.
|
||||
Assigning authority to a client causes Mirror to call OnStartAuthority() on each `NetworkBehaviour` on the game object, and sets the `hasAuthority` property to true. On other clients, the `hasAuthority` property remains false. Non-player game objects with client authority can send commands, just like players can. These commands are run on the server instance of the game object, not on the player associated with the connection.
|
||||
|
||||
If you want non-player GameObjects to have client authority, you must enable localPlayerAuthority on their Network Identity component. The example below spawns a GameObject and assigns authority to the client of the player that spawned it.
|
||||
If you want non-player game objects to have client authority, you must enable localPlayerAuthority on their Network Identity component. The example below spawns a game object and assigns authority to the client of the player that spawned it.
|
||||
|
||||
```
|
||||
[Command]
|
||||
void CmdSpawn()
|
||||
{
|
||||
var go = (GameObject)Instantiate(otherPrefab, transform.position + new Vector3(0,1,0), Quaternion.identity);
|
||||
var go = Instantiate(otherPrefab, transform.position + new Vector3(0,1,0), Quaternion.identity);
|
||||
NetworkServer.SpawnWithClientAuthority(go, connectionToClient);
|
||||
}
|
||||
```
|
||||
@ -41,11 +41,11 @@ void CmdSpawn()
|
||||
## Network Context Properties
|
||||
|
||||
The `NetworkBehaviour` class contains properties that allow scripts
|
||||
to know what the context of a networked GameObject is at any time.
|
||||
to know what the context of a networked game object is at any time.
|
||||
|
||||
- isServer - true if the GameObject is on a server (or host) and has been spawned.
|
||||
- isClient - true if the GameObject is on a client, and was created by the server.
|
||||
- isLocalPlayer - true if the GameObject is a player GameObject for this client.
|
||||
- hasAuthority - true if the GameObject is owned by the local process
|
||||
- isServer - true if the game object is on a server (or host) and has been spawned.
|
||||
- isClient - true if the game object is on a client, and was created by the server.
|
||||
- isLocalPlayer - true if the game object is a player game object for this client.
|
||||
- hasAuthority - true if the game object is owned by the local process
|
||||
|
||||
To see these properties, select the GameObject you want to inspect, and in the Inspector window, view the preview window for the NetworkBehaviour scripting components. You can use the value of these properties to execute code based on the context in which the script is running.
|
||||
To see these properties, select the game object you want to inspect, and in the Inspector window, view the preview window for the NetworkBehaviour scripting components. You can use the value of these properties to execute code based on the context in which the script is running.
|
||||
|
@ -4,9 +4,9 @@ Many multiplayer games can use the Network Manager to manage connections, but yo
|
||||
|
||||
When using the High-Level API, every game must have a host server to connect to. Each participant in a multiplayer game can be a client, a dedicated server, or a combination of server and client at the same time. This combination role is the common case of a multiplayer game with no dedicated server.
|
||||
|
||||
For multiplayer games with no dedicated server, one of the players running the game acts as the server for that game. That player’s instance of the game runs a “local client” instead of a normal remote client. The local client uses the same Scenes and GameObjects as the server, and communicates internally using message queues instead of sending messages across the network. To Mirror code and systems, the local client is just another client, so almost all user code is the same, whether a client is local or remote. This makes it easy to make a game that works in both multiplayer and standalone mode with the same code.
|
||||
For multiplayer games with no dedicated server, one of the players running the game acts as the server for that game. That player’s instance of the game runs a “local client” instead of a normal remote client. The local client uses the same Scenes and game objects as the server, and communicates internally using message queues instead of sending messages across the network. To Mirror code and systems, the local client is just another client, so almost all user code is the same, whether a client is local or remote. This makes it easy to make a game that works in both multiplayer and standalone mode with the same code.
|
||||
|
||||
A common pattern for multiplayer games is to have a GameObject that manages the network state of the game. Below is the start of a NetworkManager script. This script would be attached to a GameObject that is in the start-up Scene of the game. It has a simple UI and keyboard handling functions that allow the game to be started in different network modes. Before you release your game you should create a more visually appealing menu, with options such as “Start single player game” and “Start multiplayer game”.
|
||||
A common pattern for multiplayer games is to have a game object that manages the network state of the game. Below is the start of a NetworkManager script. This script would be attached to a game object that is in the start-up Scene of the game. It has a simple UI and keyboard handling functions that allow the game to be started in different network modes. Before you release your game you should create a more visually appealing menu, with options such as “Start single player game” and “Start multiplayer game”.
|
||||
|
||||
```
|
||||
using UnityEngine;
|
||||
|
@ -25,7 +25,7 @@ This page lists all the virtual methods (the callbacks) that you can implement o
|
||||
|
||||
## Callbacks in host mode
|
||||
|
||||
These are only called on the **Player GameObjects** when a client connects:
|
||||
These are only called on the **Player Game Objects** when a client connects:
|
||||
|
||||
- `OnStartServer`
|
||||
- `OnStartClient`
|
||||
|
@ -20,10 +20,7 @@ public class Player : NetworkBehaviour
|
||||
[Command]
|
||||
void CmdDoFire(float lifeTime)
|
||||
{
|
||||
GameObject bullet = (GameObject)Instantiate(
|
||||
bulletPrefab,
|
||||
transform.position + transform.right,
|
||||
Quaternion.identity);
|
||||
GameObject bullet = Instantiate(bulletPrefab, transform.position + transform.right, Quaternion.identity);
|
||||
|
||||
var bullet2D = bullet.GetComponent<Rigidbody2D>();
|
||||
bullet2D.velocity = transform.right * bulletSpeed;
|
||||
@ -116,6 +113,6 @@ The arguments passed to commands and ClientRpc calls are serialized and sent ove
|
||||
- structs containing allowable types
|
||||
- built-in unity math types (Vector3, Quaternion, etc)
|
||||
- NetworkIdentity
|
||||
- GameObject with a NetworkIdentity component attached
|
||||
- game object with a NetworkIdentity component attached
|
||||
|
||||
Arguments to remote actions cannot be subcomponents of GameObjects, such as script instances or Transforms. They cannot be other types that cannot be serialized across the network.
|
||||
Arguments to remote actions cannot be subcomponents of game objects, such as script instances or Transforms. They cannot be other types that cannot be serialized across the network.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Actions and Communication
|
||||
|
||||
When you are making a multiplayer game, In addition to synchronizing the properties of networked GameObjects, you are likely to need to send, receive, and react to other pieces of information - such as when the match starts, when a player joins or leaves the match, or other information specific to your type of game, for example a notification to all players that a flag has been captured in a “capture-the-flag” style game.
|
||||
When you are making a multiplayer game, In addition to synchronizing the properties of networked game objects, you are likely to need to send, receive, and react to other pieces of information - such as when the match starts, when a player joins or leaves the match, or other information specific to your type of game, for example a notification to all players that a flag has been captured in a “capture-the-flag” style game.
|
||||
|
||||
Within the Mirror networking High-Level API there are three main ways to communicate this type of information.
|
||||
|
||||
@ -10,11 +10,11 @@ Remote actions allow you to call a method in your script across the network. You
|
||||
|
||||
## Networking Callbacks
|
||||
|
||||
Networking callbacks allow you to hook into built-in Mirror events which occur during the course of the game, such as when players join or leave, when GameObjects are created or destroyed, or when a new Scene is loaded. There are two types of networking callbacks that you can implement:
|
||||
Networking callbacks allow you to hook into built-in Mirror events which occur during the course of the game, such as when players join or leave, when game objects are created or destroyed, or when a new Scene is loaded. There are two types of networking callbacks that you can implement:
|
||||
|
||||
- Network manager callbacks, for callbacks relating to the network manager itself (such as when clients connect or disconnect)
|
||||
- Network behaviour callbacks, for callbacks relating to individual networked GameObjects (such as when its Start function is called, or what this particular GameObject should do if a new player joins the game)
|
||||
- Network behaviour callbacks, for callbacks relating to individual networked game objects (such as when its Start function is called, or what this particular game object should do if a new player joins the game)
|
||||
|
||||
## Network Messages
|
||||
|
||||
Network messages are a “lower level” approach to sending messages (although they are still classed as part of the networking “High level API”). They allow you to send data directly between clients and the server using scripting. You can send basic types of data (int, string, etc) as well as most common Unity types (such as Vector3). Since you implement this yourself, these messages are not associated directly with any particular GameObjects or Unity events - it is up to you do decide their purpose and implement them!
|
||||
Network messages are a “lower level” approach to sending messages (although they are still classed as part of the networking “High level API”). They allow you to send data directly between clients and the server using scripting. You can send basic types of data (int, string, etc) as well as most common Unity types (such as Vector3). Since you implement this yourself, these messages are not associated directly with any particular game objects or Unity events - it is up to you do decide their purpose and implement them!
|
||||
|
@ -4,19 +4,19 @@ This document describes steps to converting a single player game to a multiplaye
|
||||
|
||||
## NetworkManager set-up
|
||||
|
||||
- Add a new GameObject and rename it “NetworkManager”.
|
||||
- Add the NetworkManager component to the “NetworkManager” GameObject.
|
||||
- Add the NetworkManagerHUD component to the GameObject. This provides the default UI for managing the network game state.
|
||||
- Add a new game object and rename it “NetworkManager”.
|
||||
- Add the NetworkManager component to the “NetworkManager” game object.
|
||||
- Add the NetworkManagerHUD component to the game object. This provides the default UI for managing the network game state.
|
||||
|
||||
See Using the NetworkManager.
|
||||
|
||||
## Player Prefab Setup
|
||||
|
||||
- Find the Prefab for the player GameObject in the game, or create a Prefab from the player GameObject
|
||||
- Find the Prefab for the player game object in the game, or create a Prefab from the player game object
|
||||
- Add the NetworkIdentity component to the player Prefab
|
||||
- Check the LocalPlayerAuthority box on the NetworkIdentity
|
||||
- Set the `playerPrefab` in the NetworkManager’s Spawn Info section to the player Prefab
|
||||
- Remove the player GameObject instance from the Scene if it exists in the Scene
|
||||
- Remove the player game object instance from the Scene if it exists in the Scene
|
||||
|
||||
See Player Objects for more information.
|
||||
|
||||
@ -61,7 +61,7 @@ See State Synchronization.
|
||||
|
||||
See Networked Actions.
|
||||
|
||||
## Non-player GameObjects
|
||||
## Non-player Game Objects
|
||||
|
||||
Fix non-player prefabs such as enemies:
|
||||
|
||||
@ -74,18 +74,18 @@ Fix non-player prefabs such as enemies:
|
||||
|
||||
- Potentially change spawner scripts to be NetworkBehaviours
|
||||
- Modify spawners to only run on the server (use isServer property or the `OnStartServer()` function)
|
||||
- Call `NetworkServer.Spawn()` for created GameObjects
|
||||
- Call `NetworkServer.Spawn()` for created game objects
|
||||
|
||||
## Spawn Positions for Players
|
||||
|
||||
- Add a new GameObject and place it at player’s start location
|
||||
- Add the NetworkStartPosition component to the new GameObject
|
||||
- Add a new game object and place it at player’s start location
|
||||
- Add the NetworkStartPosition component to the new game object
|
||||
|
||||
## Lobby
|
||||
|
||||
- Create Lobby Scene
|
||||
- Add a new GameObject to the Scene and rename it to “NetworkLobbyManager”.
|
||||
- Add the NetworkLobbyManager component to the new GameObject.
|
||||
- Add a new game object to the Scene and rename it to “NetworkLobbyManager”.
|
||||
- Add the NetworkLobbyManager component to the new game object.
|
||||
- Configure the Manager:
|
||||
- Scenes
|
||||
- Prefabs
|
||||
|
@ -5,11 +5,11 @@ Mirror provides tools to get information about your game at run time. This infor
|
||||
When your game is running in the Editor in Play mode, the Network Manager shows additional information about the state of the network at runtime. This includes:
|
||||
|
||||
- Network connections
|
||||
- Active GameObjects on the server which have a Network Identity component
|
||||
- Active GameObjects on the client which have a Network Identity component
|
||||
- Active game objects on the server which have a Network Identity component
|
||||
- Active game objects on the client which have a Network Identity component
|
||||
- Client peers
|
||||
|
||||
![In Play Mode, the Network Manager HUD component displays additional information about the state of the game and the GameObjects that have spawned.](NetworkManagerHUDDebugging1.jpg)
|
||||
![In Play Mode, the Network Manager HUD component displays additional information about the state of the game and the game objects that have spawned.](NetworkManagerHUDDebugging1.jpg)
|
||||
|
||||
Additionally, the Network Manager preview pane (at the bottom of the Inspector window) lists the registered message callback handlers.
|
||||
|
||||
|
@ -1,24 +1,24 @@
|
||||
# Scene GameObjects
|
||||
# Scene Game Objects
|
||||
|
||||
There are two types of networked GameObjects in Mirror’s multiplayer system:
|
||||
There are two types of networked game objects in Mirror’s multiplayer system:
|
||||
|
||||
- Those that are created dynamically at runtime
|
||||
- Those that are saved as part of a Scene
|
||||
|
||||
GameObjects that are created dynamically at runtime use the multiplayer Spawning system, and the prefabs they are instantiated from must be registered in the Network Manager’s list of networked GameObject prefabs.
|
||||
Game objects that are created dynamically at runtime use the multiplayer Spawning system, and the prefabs they are instantiated from must be registered in the Network Manager’s list of networked game object prefabs.
|
||||
|
||||
However, networked GameObjects that you save as part of a Scene (and therefore already exist in the Scene when it is loaded) are handled differently. These GameObjects are loaded as part of the Scene on both the client and server, and exist at runtime before any spawn messages are sent by the multiplayer system.
|
||||
However, networked game objects that you save as part of a Scene (and therefore already exist in the Scene when it is loaded) are handled differently. These game objects are loaded as part of the Scene on both the client and server, and exist at runtime before any spawn messages are sent by the multiplayer system.
|
||||
|
||||
When the Scene is loaded, all networked GameObjects in the Scene are disabled on both the client and the server. Then, when the Scene is fully loaded, the Network Manager automatically processes the Scene’s networked GameObjects, registering them all (and therefore causing them to be synchronized across clients), and enabling them, as if they were spawned at runtime.
|
||||
When the Scene is loaded, all networked game objects in the Scene are disabled on both the client and the server. Then, when the Scene is fully loaded, the Network Manager automatically processes the Scene’s networked game objects, registering them all (and therefore causing them to be synchronized across clients), and enabling them, as if they were spawned at runtime.
|
||||
|
||||
Saving networked GameObjects in your Scene (rather than dynamically spawning them after the scene has loaded) has some benefits:
|
||||
Saving networked game objects in your Scene (rather than dynamically spawning them after the scene has loaded) has some benefits:
|
||||
|
||||
- They are loaded with the level, so there will be no pause at runtime.
|
||||
- They can have specific modifications that differ from prefabs
|
||||
- Other GameObject instances in the Scene can reference them, which can avoid you having to use code to finding the GameObjects and make references to them up at runtime.
|
||||
- Other game object instances in the Scene can reference them, which can avoid you having to use code to finding the game objects and make references to them up at runtime.
|
||||
|
||||
When the Network Manager spawns the networked Scene GameObjects, those GameObjects behave like dynamically spawned GameObjects. Mirror sends them updates and ClientRPC calls.
|
||||
When the Network Manager spawns the networked Scene game objects, those game objects behave like dynamically spawned game objects. Mirror sends them updates and ClientRPC calls.
|
||||
|
||||
If a Scene GameObject is destroyed on the server before a client joins the game, then it is never enabled on new clients that join.
|
||||
If a Scene game object is destroyed on the server before a client joins the game, then it is never enabled on new clients that join.
|
||||
|
||||
When a client connects, the client is sent an ObjectSpawnScene spawn message for each of the Scene GameObjects that exist on the server, that are visible to that client. This message causes the GameObject on the client to be enabled, and has the latest state of that GameObject from the server in it. This means that only GameObjects that are visible to the client, and not destroyed on the server, are activated on the client. Like regular non-Scene GameObjects, these Scene GameObjects are started with the latest state when the client joins the game.
|
||||
When a client connects, the client is sent an ObjectSpawnScene spawn message for each of the Scene game objects that exist on the server, that are visible to that client. This message causes the game object on the client to be enabled, and has the latest state of that game object from the server in it. This means that only game objects that are visible to the client, and not destroyed on the server, are activated on the client. Like regular non-Scene game objects, these Scene game objects are started with the latest state when the client joins the game.
|
||||
|
@ -1,22 +1,22 @@
|
||||
# Spawning GameObjects
|
||||
# Spawning Game Objects
|
||||
|
||||
In Mirror, you usually “spawn” (that is, create) new GameObjects with `Instantiate`. However, in the multiplayer High Level API, the word “spawn” means something more specific. In the server-authoritative model of the HLAPI, to “spawn” a GameObject on the server means that the GameObject is created on clients connected to the server, and is managed by the spawning system.
|
||||
In Mirror, you usually “spawn” (that is, create) new game objects with `Instantiate`. However, in the multiplayer High Level API, the word “spawn” means something more specific. In the server-authoritative model of the HLAPI, to “spawn” a game object on the server means that the game object is created on clients connected to the server, and is managed by the spawning system.
|
||||
|
||||
Once the GameObject is spawned using this system, state updates are sent to clients whenever the GameObject changes on the server. When Mirror destroys the GameObject on the server, it also destroys it on the clients. The server manages spawned GameObjects alongside all other networked GameObjects, so that if another client joins the game later, the server can spawn the GameObjects on that client. These spawned GameObjects have a unique network instance ID called “netId” that is the same on the server and clients for each GameObject. The unique network instance ID is used to route messages set across the network to GameObjects, and to identify GameObjects.
|
||||
Once the game object is spawned using this system, state updates are sent to clients whenever the game object changes on the server. When Mirror destroys the game object on the server, it also destroys it on the clients. The server manages spawned game objects alongside all other networked game objects, so that if another client joins the game later, the server can spawn the game objects on that client. These spawned game objects have a unique network instance ID called “netId” that is the same on the server and clients for each game object. The unique network instance ID is used to route messages set across the network to game objects, and to identify game objects.
|
||||
|
||||
When the server spawns a GameObject with a Network Identity component, the GameObject spawned on the client has the same “state”. This means it is identical to the GameObject on the server; it has the same Transform, movement state, and (if NetworkTransform and SyncVars are used) synchronized variables. Therefore, client GameObjects are always up-to-date when Mirror creates them. This avoids issues such as GameObjects spawning at the wrong initial location, then reappearing at their correct position when a state update arrives.
|
||||
When the server spawns a game object with a Network Identity component, the game object spawned on the client has the same “state”. This means it is identical to the game object on the server; it has the same Transform, movement state, and (if NetworkTransform and SyncVars are used) synchronized variables. Therefore, client game objects are always up-to-date when Mirror creates them. This avoids issues such as game objects spawning at the wrong initial location, then reappearing at their correct position when a state update arrives.
|
||||
|
||||
The Network Manager before trying to register it with the Network Manager.
|
||||
|
||||
To register a Prefab with the Network Manager in the Editor, select the Network Manager GameObject, and in the Inspector, navigate to the Network Manager component. Click the triangle next to Spawn Info to open the settings, then under Registered Spawnable Prefabs, click the plus (+) button. Drag and drop Prefabs into the empty field to assign them to the list.
|
||||
To register a Prefab with the Network Manager in the Editor, select the Network Manager game object, and in the Inspector, navigate to the Network Manager component. Click the triangle next to Spawn Info to open the settings, then under Registered Spawnable Prefabs, click the plus (+) button. Drag and drop Prefabs into the empty field to assign them to the list.
|
||||
|
||||
![The Network Manager Inspector with the Spawn Info foldout expanded, displaying three assigned Prefabs under Registered Spawnable Prefabs](UNetManagerSpawnInfo.png)
|
||||
|
||||
## Spawning Without Network Manager
|
||||
|
||||
For more advanced users, you may find that you want to register Prefabs and spawn GameObjects without using the NetworkManager component.
|
||||
For more advanced users, you may find that you want to register Prefabs and spawn game objects without using the NetworkManager component.
|
||||
|
||||
To spawn GameObjects without using the Network Manager, you can handle the Prefab registration yourself via script. Use the ClientScene.RegisterPrefab method to register Prefabs to the Network Manager.
|
||||
To spawn game objects without using the Network Manager, you can handle the Prefab registration yourself via script. Use the ClientScene.RegisterPrefab method to register Prefabs to the Network Manager.
|
||||
|
||||
### Example: MyNetworkManager
|
||||
|
||||
@ -43,7 +43,7 @@ public class MyNetworkManager : MonoBehaviour
|
||||
}
|
||||
```
|
||||
|
||||
In this example, you create an empty GameObject to act as the Network Manager, then create and attach the `MyNetworkManager` script (above) to that GameObject. Create a Prefab that has a Network Identity component attached to it, and drag that onto the treePrefab slot on the MyNetworkManager component in the Inspector. This ensures that when the server spawns the tree GameObject, it also creates the same kind of GameObject on the clients.
|
||||
In this example, you create an empty game object to act as the Network Manager, then create and attach the `MyNetworkManager` script (above) to that game object. Create a Prefab that has a Network Identity component attached to it, and drag that onto the treePrefab slot on the MyNetworkManager component in the Inspector. This ensures that when the server spawns the tree game object, it also creates the same kind of game object on the clients.
|
||||
|
||||
Registering Prefabs ensures that the Asset, so that there is no stalling or loading time for creating the Asset.
|
||||
|
||||
@ -83,13 +83,13 @@ void OnServerConnect(NetworkMessage msg)
|
||||
}
|
||||
```
|
||||
|
||||
The server does not need to register anything, as it knows what GameObject is being spawned (and the asset ID is sent in the spawn message). The client needs to be able to look up the GameObject, so it must be registered on the client.
|
||||
The server does not need to register anything, as it knows what game object is being spawned (and the asset ID is sent in the spawn message). The client needs to be able to look up the game object, so it must be registered on the client.
|
||||
|
||||
When writing your own network manager, it’s important to make the client ready to receive state updates before calling the spawn command on the server, otherwise they won’t be sent. If you’re using Mirror’s built-in Network Manager component, this happens automatically.
|
||||
|
||||
For more advanced uses, such as object pools or dynamically created Assets, you can use the ClientScene.RegisterSpawnHandler method, which allows callback functions to be registered for client-side spawning. See documentation on Custom Spawn Functions for an example of this.
|
||||
|
||||
If the GameObject has a network state like synchronized variables, then that state is synchronized with the spawn message. In the following example, this script is attached to the tree Prefab:
|
||||
If the game object has a network state like synchronized variables, then that state is synchronized with the spawn message. In the following example, this script is attached to the tree Prefab:
|
||||
|
||||
```
|
||||
using UnityEngine;
|
||||
@ -128,15 +128,15 @@ Attach the `Tree` script to the `treePrefab` script created earlier to see this
|
||||
|
||||
### Constraints
|
||||
|
||||
- A NetworkIdentity must be on the root GameObject of a spawnable Prefab. Without this, the Network Manager can’t register the Prefab.
|
||||
- NetworkBehaviour scripts must be on the same GameObject as the NetworkIdentity, not on child GameObjects
|
||||
- A NetworkIdentity must be on the root game object of a spawnable Prefab. Without this, the Network Manager can’t register the Prefab.
|
||||
- NetworkBehaviour scripts must be on the same game object as the NetworkIdentity, not on child game objects
|
||||
|
||||
## GameObject Creation Flow
|
||||
## Game Object Creation Flow
|
||||
|
||||
The actual flow of internal operations that takes place for spawning GameObjects is:
|
||||
The actual flow of internal operations that takes place for spawning game objects is:
|
||||
|
||||
- Prefab with Network Identity component is registered as spawnable.
|
||||
- GameObject is instantiated from the Prefab on the server.
|
||||
- game object is instantiated from the Prefab on the server.
|
||||
- Game code sets initial values on the instance (note that 3D physics forces applied here do not take effect immediately).
|
||||
- `NetworkServer.Spawn` is called with the instance.
|
||||
- The state of the SyncVars on the instance on the server are collected by calling `OnSerialize` on [Network Behaviour] components.
|
||||
@ -150,34 +150,34 @@ The actual flow of internal operations that takes place for spawning GameObjects
|
||||
- A network message of type `MsgType.ObjectDestroy` is sent to clients.
|
||||
- `OnNetworkDestroy` is called on the instance on clients, then the instance is destroyed.
|
||||
|
||||
### Player GameObjects
|
||||
### Player Game Objects
|
||||
|
||||
Player GameObjects in the HLAPI work slightly differently to non-player GameObjects. The flow for spawning player GameObjects with the Network Manager is:
|
||||
Player game objects in the HLAPI work slightly differently to non-player game objects. The flow for spawning player game objects with the Network Manager is:
|
||||
|
||||
- Prefab with `NetworkIdentity` is registered as the `PlayerPrefab`
|
||||
- Client connects to the server
|
||||
- Client calls `AddPlayer`, network message of type `MsgType.AddPlayer` is sent to the server
|
||||
- Server receives message and calls `NetworkManager.OnServerAddPlayer`
|
||||
- GameObject is instantiated from the PlayerPrefab on the server
|
||||
- game object is instantiated from the PlayerPrefab on the server
|
||||
- `NetworkManager.AddPlayerForConnection` is called with the new player instance on the server
|
||||
- The player instance is spawned - you do not have to call `NetworkServer.Spawn` for the player instance. The spawn message is sent to all clients like on a normal spawn.
|
||||
- A network message of type `MsgType.Owner` is sent to the client that added the player (only that client!)
|
||||
- The original client receives the network message
|
||||
- `OnStartLocalPlayer` is called on the player instance on the original client, and `isLocalPlayer` is set to true
|
||||
|
||||
Note that `OnStartLocalPlayer` is called after `OnStartClient`, because it only happens when the ownership message arrives from the server after the player GameObject is spawned, so `isLocalPlayer` is not set in `OnStartClient`.
|
||||
Note that `OnStartLocalPlayer` is called after `OnStartClient`, because it only happens when the ownership message arrives from the server after the player game object is spawned, so `isLocalPlayer` is not set in `OnStartClient`.
|
||||
|
||||
Because `OnStartLocalPlayer` is only called for the client’s local player GameObject, it is a good place to perform initialization that should only be done for the local player. This could include enabling input processing, and enabling camera tracking for the player GameObject.
|
||||
Because `OnStartLocalPlayer` is only called for the client’s local player game object, it is a good place to perform initialization that should only be done for the local player. This could include enabling input processing, and enabling camera tracking for the player game object.
|
||||
|
||||
## Spawning GameObjects with Client Authority
|
||||
## Spawning Game Objects with Client Authority
|
||||
|
||||
To spawn GameObjects and assign authority of those GameObjects to a particular client, use NetworkServer.SpawnWithClientAuthority, which takes as an argument the `NetworkConnection` of the client that is to be made the authority.
|
||||
To spawn game objects and assign authority of those game objects to a particular client, use NetworkServer.SpawnWithClientAuthority, which takes as an argument the `NetworkConnection` of the client that is to be made the authority.
|
||||
|
||||
For these GameObjects, the property `hasAuthority` is true on the client with authority, and `OnStartAuthority` is called on the client with authority. That client can issue commands for that GameObject. On other clients (and on the host), `hasAuthority` is false.
|
||||
For these game objects, the property `hasAuthority` is true on the client with authority, and `OnStartAuthority` is called on the client with authority. That client can issue commands for that game object. On other clients (and on the host), `hasAuthority` is false.
|
||||
|
||||
Objects spawned with client authority must have `LocalPlayerAuthority` set in their `NetworkIdentity`.
|
||||
|
||||
For example, the tree spawn example above can be modified to allow the tree to have client authority like this (note that we now need to pass in a NetworkConnection GameObject for the owning client’s connection):
|
||||
For example, the tree spawn example above can be modified to allow the tree to have client authority like this (note that we now need to pass in a NetworkConnection game object for the owning client’s connection):
|
||||
|
||||
```
|
||||
void SpawnTrees(NetworkConnection conn)
|
||||
|
@ -1,16 +1,16 @@
|
||||
# Custom Spawn Functions
|
||||
|
||||
You can use spawn handler functions to customize the default behavior when creating spawned GameObjects on the client. Spawn handler functions ensure you have full control of how you spawn the GameObject, as well as how you destroy it.
|
||||
You can use spawn handler functions to customize the default behavior when creating spawned game objects on the client. Spawn handler functions ensure you have full control of how you spawn the game object, as well as how you destroy it.
|
||||
|
||||
Use ClientScene.RegisterSpawnHandler to register functions to spawn and destroy client GameObjects. The server creates GameObjects directly, and then spawns them on the clients through this functionality. This function takes the asset ID of the GameObject and two function delegates: one to handle creating GameObjects on the client, and one to handle destroying GameObjects on the client. The asset ID can be a dynamic one, or just the asset ID found on the prefab GameObject you want to spawn (if you have one).
|
||||
Use ClientScene.RegisterSpawnHandler to register functions to spawn and destroy client game objects. The server creates game objects directly, and then spawns them on the clients through this functionality. This function takes the asset ID of the game object and two function delegates: one to handle creating game objects on the client, and one to handle destroying game objects on the client. The asset ID can be a dynamic one, or just the asset ID found on the prefab game object you want to spawn (if you have one).
|
||||
|
||||
The spawn / un-spawner need to have this GameObject signature. This is defined in the high level API.
|
||||
The spawn / un-spawner need to have this game object signature. This is defined in the high level API.
|
||||
|
||||
```cs
|
||||
// Handles requests to spawn GameObjects on the client
|
||||
// Handles requests to spawn game objects on the client
|
||||
public delegate GameObject SpawnDelegate(Vector3 position, System.Guid assetId);
|
||||
|
||||
// Handles requests to unspawn GameObjects on the client
|
||||
// Handles requests to unspawn game objects on the client
|
||||
public delegate void UnSpawnDelegate(GameObject spawned);
|
||||
```
|
||||
|
||||
@ -38,7 +38,7 @@ The spawn functions themselves are implemented with the delegate signature. Here
|
||||
```cs
|
||||
public GameObject SpawnCoin(Vector3 position, System.Guid assetId)
|
||||
{
|
||||
return (GameObject)Instantiate(m_CoinPrefab, position, Quaternion.identity);
|
||||
return Instantiate(m_CoinPrefab, position, Quaternion.identity);
|
||||
}
|
||||
public void UnSpawnCoin(GameObject spawned)
|
||||
{
|
||||
@ -46,13 +46,13 @@ public void UnSpawnCoin(GameObject spawned)
|
||||
}
|
||||
```
|
||||
|
||||
When using custom spawn functions, it is sometimes useful to be able to unspawn GameObjects without destroying them. This can be done by calling [NetworkServer.UnSpawn]. This causes a message to be sent to clients to un-spawn the GameObject, so that the custom un-spawn function will be called on the clients. The GameObject is not destroyed when this function is called.
|
||||
When using custom spawn functions, it is sometimes useful to be able to unspawn game objects without destroying them. This can be done by calling [NetworkServer.UnSpawn]. This causes a message to be sent to clients to un-spawn the game object, so that the custom un-spawn function will be called on the clients. The game object is not destroyed when this function is called.
|
||||
|
||||
Note that on the host, GameObjects are not spawned for the local client, because they already exist on the server. This also means that no spawn handler functions are called.
|
||||
Note that on the host, game objects are not spawned for the local client, because they already exist on the server. This also means that no spawn handler functions are called.
|
||||
|
||||
## Setting Up a GameObject Pool with Custom Spawn Handlers
|
||||
## Setting Up a Game Object Pool with Custom Spawn Handlers
|
||||
|
||||
Here is an example of how you might set up a very simple GameObject pooling system with custom spawn handlers. Spawning and unspawning then puts GameObjects in or out of the pool.
|
||||
Here is an example of how you might set up a very simple game object pooling system with custom spawn handlers. Spawning and unspawning then puts game objects in or out of the pool.
|
||||
|
||||
```cs
|
||||
using UnityEngine;
|
||||
@ -77,7 +77,7 @@ public class SpawnManager : MonoBehaviour
|
||||
m_Pool = new GameObject[m_ObjectPoolSize];
|
||||
for (int i = 0; i < m_ObjectPoolSize; ++i)
|
||||
{
|
||||
m_Pool[i] = (GameObject)Instantiate(m_Prefab, Vector3.zero, Quaternion.identity);
|
||||
m_Pool[i] = Instantiate(m_Prefab, Vector3.zero, Quaternion.identity);
|
||||
m_Pool[i].name = "PoolObject" + i;
|
||||
m_Pool[i].SetActive(false);
|
||||
}
|
||||
@ -97,7 +97,7 @@ public class SpawnManager : MonoBehaviour
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
Debug.LogError ("Could not grab GameObject from pool, nothing available");
|
||||
Debug.LogError ("Could not grab game object from pool, nothing available");
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -108,13 +108,13 @@ public class SpawnManager : MonoBehaviour
|
||||
|
||||
public void UnSpawnObject(GameObject spawned)
|
||||
{
|
||||
Debug.Log ("Re-pooling GameObject " + spawned.name);
|
||||
Debug.Log ("Re-pooling game object " + spawned.name);
|
||||
spawned.SetActive (false);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To use this manager, create a new empty GameObject and name it “SpawnManager”. Create a new script called *SpawnManager,* copy in the code sample above, and attach it to the\* \*new SpawnManager GameObject. Next, drag a prefab you want to spawn multiple times to the Prefab field, and set the Object Pool Size (default is 5).
|
||||
To use this manager, create a new empty game object and name it “SpawnManager”. Create a new script called *SpawnManager,* copy in the code sample above, and attach it to the new SpawnManager game object. Next, drag a prefab you want to spawn multiple times to the Prefab field, and set the Object Pool Size (default is 5).
|
||||
|
||||
Finally, set up a reference to the SpawnManager in the script you are using for player movement:
|
||||
|
||||
@ -148,7 +148,7 @@ void Update()
|
||||
}
|
||||
```
|
||||
|
||||
In the fire logic on the player, make it use the GameObject pool:
|
||||
In the fire logic on the player, make it use the game object pool:
|
||||
|
||||
```cs
|
||||
[Command]
|
||||
@ -173,4 +173,4 @@ public IEnumerator Destroy(GameObject go, float timer)
|
||||
}
|
||||
```
|
||||
|
||||
The automatic destruction shows how the GameObjects are returned to the pool and re-used when you fire again.
|
||||
The automatic destruction shows how the game objects are returned to the pool and re-used when you fire again.
|
||||
|
@ -1,13 +1,13 @@
|
||||
# Player GameObjects
|
||||
# Player Game Objects
|
||||
|
||||
Mirror’s multiplayer HLAPI system handles player GameObjects differently to non-player GameObjects. When a new player joins the game (when a new client connects to the server), that player’s GameObject becomes a “local player” GameObject on the client of that player, and Unity associates the player’s connection with the player’s GameObject. Unity associates one player GameObject for each person playing the game, and routes networking commands to that individual GameObject. A player cannot invoke a command on another player’s GameObject, only their own.
|
||||
Mirror’s multiplayer HLAPI system handles player game objects differently to non-player game objects. When a new player joins the game (when a new client connects to the server), that player’s game object becomes a “local player” game object on the client of that player, and Unity associates the player’s connection with the player’s game object. Unity associates one player game object for each person playing the game, and routes networking commands to that individual game object. A player cannot invoke a command on another player’s game object, only their own.
|
||||
|
||||
The NetworkBehaviour class (which you derive from to create your network scripts) has a property called isLocalPlayer. On each client’s player GameObject, Mirror sets that property to true on the NetworkBehaviour script, and invokes the OnStartLocalPlayer() callback. This means each client has a different GameObject set up like this, because on each client a different GameObject is the one that represents the local player. The diagram below shows two clients and their local players.
|
||||
The NetworkBehaviour class (which you derive from to create your network scripts) has a property called isLocalPlayer. On each client’s player game object, Mirror sets that property to true on the NetworkBehaviour script, and invokes the OnStartLocalPlayer() callback. This means each client has a different game object set up like this, because on each client a different game object is the one that represents the local player. The diagram below shows two clients and their local players.
|
||||
|
||||
![In this diagram, the circles represent the player GameObjects marked as the local player on each client](NetworkLocalPlayers.png)
|
||||
![In this diagram, the circles represent the player game objects marked as the local player on each client](NetworkLocalPlayers.png)
|
||||
|
||||
Only the player GameObject that is “yours” (from your point of view as the player) has the `isLocalPlayer` flag set. Usually you should set this flag in script to determine whether to process input, whether to make the camera track the GameObject, or do any other client-side things that should only occur for the player belonging to that client.
|
||||
Only the player game object that is “yours” (from your point of view as the player) has the `isLocalPlayer` flag set. Usually you should set this flag in script to determine whether to process input, whether to make the camera track the game object, or do any other client-side things that should only occur for the player belonging to that client.
|
||||
|
||||
Player GameObjects represent the player (that is, the person playing the game) on the server, and have the ability to run commands from the player’s client. These commands are secure client-to-server remote procedure calls. In this server-authoritative system, other non-player server-side GameObjects cannot receive commands directly from client-side GameObjects. This is both for security, and to reduce the complexity of building your game. By routing all incoming commands from users through the player GameObject, you can ensure that these messages come from the right place, the right client, and can be handled in a central location.
|
||||
Player game objects represent the player (that is, the person playing the game) on the server, and have the ability to run commands from the player’s client. These commands are secure client-to-server remote procedure calls. In this server-authoritative system, other non-player server-side game objects cannot receive commands directly from client-side game objects. This is both for security, and to reduce the complexity of building your game. By routing all incoming commands from users through the player game object, you can ensure that these messages come from the right place, the right client, and can be handled in a central location.
|
||||
|
||||
The Network Manager adds a player every time a client connects to the server. In some situations though, you might want it not to add players until an input event happens - such as a user pressing a “start” button on the controller. To disable automatic player creation, navigate to the Network Manager component’s Inspector and untick the Auto Create Player checkbox.
|
||||
|
@ -4,7 +4,7 @@ The Network Manager offers a built-in simple player spawning feature, however yo
|
||||
|
||||
To do this you need to override the default behavior of the Network Manager with your own script.
|
||||
|
||||
When the Network Manager adds a player, it also instantiates a GameObject from the Player Prefab and associates it with the connection. To do this, the Network Manager calls NetworkServer.AddPlayerForConnection. You can modify this behavior by overriding NetworkManager.OnServerAddPlayer. The default implementation of `OnServerAddPlayer` instantiates a new player instance from the player Prefab and calls NetworkServer.AddPlayerForConnection to spawn the new player instance. Your custom implementation of `OnServerAddPlayer` must also call `NetworkServer.AddPlayerForConnection`, but your are free to perform any other initialization you require in that method too.
|
||||
When the Network Manager adds a player, it also instantiates a game object from the Player Prefab and associates it with the connection. To do this, the Network Manager calls NetworkServer.AddPlayerForConnection. You can modify this behavior by overriding NetworkManager.OnServerAddPlayer. The default implementation of `OnServerAddPlayer` instantiates a new player instance from the player Prefab and calls NetworkServer.AddPlayerForConnection to spawn the new player instance. Your custom implementation of `OnServerAddPlayer` must also call `NetworkServer.AddPlayerForConnection`, but your are free to perform any other initialization you require in that method too.
|
||||
|
||||
The example below customizes the color of a player. First, add the color script to the player prefab:
|
||||
|
||||
@ -28,7 +28,7 @@ public class MyNetworkManager : NetworkManager
|
||||
{
|
||||
public override void OnServerAddPlayer(NetworkConnection conn, AddPlayerMessage extraMessage)
|
||||
{
|
||||
GameObject player = (GameObject)Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
|
||||
GameObject player = (game object)Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
|
||||
player.GetComponent<Player>().color = Color.red;
|
||||
NetworkServer.AddPlayerForConnection(conn, player);
|
||||
}
|
||||
@ -37,21 +37,21 @@ public class MyNetworkManager : NetworkManager
|
||||
|
||||
The function `NetworkServer.AddPlayerForConnection` does not have to be called from within `OnServerAddPlayer`. As long as the correct connection object and `playerControllerId` are passed in, it can be called after `OnServerAddPlayer` has returned. This allows asynchronous steps to happen in between, such as loading player data from a remote data source.
|
||||
|
||||
The system automatically spawns the player GameObject passed to `NetworkServer.AddPlayerForConnection` on the server, so you don’t need to call NetworkServer.Spawn for the player. Once a player is ready, the active networked GameObjects (that is, GameObjects with an associated NetworkIdentity) in the Scene spawn on the player’s client. All networked GameObjects in the game are created on that client with their latest state, so they are in sync with the other participants of the game.
|
||||
The system automatically spawns the player game object passed to `NetworkServer.AddPlayerForConnection` on the server, so you don’t need to call NetworkServer.Spawn for the player. Once a player is ready, the active networked game objects (that is, game objects with an associated NetworkIdentity) in the Scene spawn on the player’s client. All networked game objects in the game are created on that client with their latest state, so they are in sync with the other participants of the game.
|
||||
|
||||
You don’t need to use playerPrefab on the `NetworkManager` to create player GameObjects. You could use different methods of creating different players.
|
||||
You don’t need to use playerPrefab on the `NetworkManager` to create player game objects. You could use different methods of creating different players.
|
||||
|
||||
## Ready State
|
||||
|
||||
In addition to players, client connections also have a “ready” state. The host sends clients that are ready information about spawned GameObjects and state synchronization updates; clients which are not ready are not sent these updates. When a client initially connects to a server, it is not ready. While in this non-ready state, the client can do things that don’t require real-time interactions with the game state on the server, such as loading Scenes, allowing the player to choose an avatar, or fill in log-in boxes. Once a client has completed all its pre-game work, and all its Assets are loaded, it can call ClientScene.Ready to enter the “ready” state. The simple example above demonstrates implementation of ready states; because adding a player with `NetworkServer.AddPlayerForConnection` also puts the client into the ready state if it is not already in that state.
|
||||
In addition to players, client connections also have a “ready” state. The host sends clients that are ready information about spawned game objects and state synchronization updates; clients which are not ready are not sent these updates. When a client initially connects to a server, it is not ready. While in this non-ready state, the client can do things that don’t require real-time interactions with the game state on the server, such as loading Scenes, allowing the player to choose an avatar, or fill in log-in boxes. Once a client has completed all its pre-game work, and all its Assets are loaded, it can call ClientScene.Ready to enter the “ready” state. The simple example above demonstrates implementation of ready states; because adding a player with `NetworkServer.AddPlayerForConnection` also puts the client into the ready state if it is not already in that state.
|
||||
|
||||
Clients can send and receive network messages without being ready, which also means they can do so without having an active player GameObject. So a client at a menu or selection screen can connect to the game and interact with it, even though they have no player GameObject. See documentation on Network messages for more details about sending messages without using commands and RPC calls.
|
||||
Clients can send and receive network messages without being ready, which also means they can do so without having an active player game object. So a client at a menu or selection screen can connect to the game and interact with it, even though they have no player game object. See documentation on Network messages for more details about sending messages without using commands and RPC calls.
|
||||
|
||||
## Switching Players
|
||||
|
||||
To replace the player GameObject for a connection, use NetworkServer.ReplacePlayerForConnection. This is useful for restricting the commands that players can issue at certain times, such as in a pre-game lobby screen. This function takes the same arguments as `AddPlayerForConnection`, but allows there to already be a player for that connection. The old player GameObject does not have to be destroyed. The NetworkLobbyManager uses this technique to switch from the NetworkLobbyPlayer GameObject to a gameplay player GameObject when all the players in the lobby are ready.
|
||||
To replace the player game object for a connection, use NetworkServer.ReplacePlayerForConnection. This is useful for restricting the commands that players can issue at certain times, such as in a pre-game lobby screen. This function takes the same arguments as `AddPlayerForConnection`, but allows there to already be a player for that connection. The old player game object does not have to be destroyed. The NetworkLobbyManager uses this technique to switch from the NetworkLobbyPlayer game object to a gameplay player game object when all the players in the lobby are ready.
|
||||
|
||||
You can also use `ReplacePlayerForConnection` to respawn a player after their GameObject is destroyed. In some cases it is better to just disable a GameObject and reset its game attributes on respawn. The following code sample demonstrates how to actually replace the destroyed GameObject with a new GameObject:
|
||||
You can also use `ReplacePlayerForConnection` to respawn a player after their game object is destroyed. In some cases it is better to just disable a game object and reset its game attributes on respawn. The following code sample demonstrates how to actually replace the destroyed game object with a new game object:
|
||||
|
||||
```
|
||||
class GameManager
|
||||
@ -66,8 +66,8 @@ class GameManager
|
||||
}
|
||||
```
|
||||
|
||||
If the player GameObject for a connection is destroyed, then that client cannot execute Commands. They can, however, still send network messages.
|
||||
If the player game object for a connection is destroyed, then that client cannot execute Commands. They can, however, still send network messages.
|
||||
|
||||
To use `ReplacePlayerForConnection` you must have the NetworkConnection GameObject for the player’s client to establish the relationship between the GameObject and the client. This is usually the property connectionToClient on the NetworkBehaviour class, but if the old player has already been destroyed, then that might not be readily available.
|
||||
To use `ReplacePlayerForConnection` you must have the NetworkConnection game object for the player’s client to establish the relationship between the game object and the client. This is usually the property connectionToClient on the NetworkBehaviour class, but if the old player has already been destroyed, then that might not be readily available.
|
||||
|
||||
To find the connection, there are some lists available. If using the `NetworkLobbyManager`, then the lobby players are available in lobbySlots. The NetworkServer also has lists of connections and localConnections.
|
||||
|
@ -1,17 +1,17 @@
|
||||
# Networked GameObjects
|
||||
# Networked Game Objects
|
||||
|
||||
Networked GameObjects are GameObjects which are controlled and synchronized by Mirror’s networking system. Using synchronized networked GameObjects, you can create a shared experience for all the players who are playing an instance of your game. They see and hear the same events and actions - even though that may be from their own unique viewpoints within your game.
|
||||
Networked game objects are game objects which are controlled and synchronized by Mirror’s networking system. Using synchronized networked game objects, you can create a shared experience for all the players who are playing an instance of your game. They see and hear the same events and actions - even though that may be from their own unique viewpoints within your game.
|
||||
|
||||
Multiplayer games in Mirror are typically built using Scenes that contain a mix of networked GameObjects and regular (non-networked) GameObjects. The networked GameObjects are those which move or change during gameplay in a way that needs to be synchronized across all users who are playing the game together. Non-networked GameObjects are those which either don’t move or change at all during gameplay (for example, static obstacles like rocks or fences), or GameObjects which have movement or changes that don’t need to be synchronized across players (for example, a gently swaying tree or clouds passing by in the background of your game).
|
||||
Multiplayer games in Mirror are typically built using Scenes that contain a mix of networked game objects and regular (non-networked) game objects. The networked game objects are those which move or change during gameplay in a way that needs to be synchronized across all users who are playing the game together. Non-networked game objects are those which either don’t move or change at all during gameplay (for example, static obstacles like rocks or fences), or game objects which have movement or changes that don’t need to be synchronized across players (for example, a gently swaying tree or clouds passing by in the background of your game).
|
||||
|
||||
A networked GameObject is one which has a Network Identity component attached. However, a Network Identity component alone is not enough for your GameObject to be functional and active in your multiplayer game. The Network Identity component is the starting point for synchronization, and it allows the Network Manager to synchronize the creation and destruction of the GameObject, but other than that, it does not specify *which properties* of your GameObject should be synchronized.
|
||||
A networked game object is one which has a Network Identity component attached. However, a Network Identity component alone is not enough for your game object to be functional and active in your multiplayer game. The Network Identity component is the starting point for synchronization, and it allows the Network Manager to synchronize the creation and destruction of the game object, but other than that, it does not specify *which properties* of your game object should be synchronized.
|
||||
|
||||
What exactly should be synchronized on each networked GameObject depends on the type of game you are making, and what each GameObject’s purpose is. Some examples of what you might want to synchronize are:
|
||||
What exactly should be synchronized on each networked game object depends on the type of game you are making, and what each game object’s purpose is. Some examples of what you might want to synchronize are:
|
||||
|
||||
- The position and rotation of moving GameObjects such as the players and non-player characters.
|
||||
- The animation state of an animated GameObject
|
||||
- The position and rotation of moving game objects such as the players and non-player characters.
|
||||
- The animation state of an animated game object
|
||||
- The value of a variable, for example how much time is left in the current round of a game, or how much energy a player has.
|
||||
|
||||
Some of these things can be automatically synchronized by Mirror. The synchronized creation and destruction of networked GameObjects is managed by the NetworkManager, and is known as Spawning. You can use the Network Transform component to synchronize the position and rotation of a GameObject, and you can use the Network Animator component to synchronize the animation of a GameObject.
|
||||
Some of these things can be automatically synchronized by Mirror. The synchronized creation and destruction of networked game objects is managed by the NetworkManager, and is known as Spawning. You can use the Network Transform component to synchronize the position and rotation of a game object, and you can use the Network Animator component to synchronize the animation of a game object.
|
||||
|
||||
To synchronize other properties of a networked GameObject, you need to use scripting. See State Synchronization for more information about this.
|
||||
To synchronize other properties of a networked game object, you need to use scripting. See State Synchronization for more information about this.
|
||||
|
@ -44,16 +44,16 @@ One of the aims of the multiplayer system is for the code for local clients and
|
||||
|
||||
## Instantiate and Spawn
|
||||
|
||||
When you make a single player game In Mirror, you usually use the `GameObject.Instantiate` method to create new GameObjects at runtime. However, with a multiplayer system, the server itself must “spawn” GameObjects in order for them to be active within the networked game. When the server spawns GameObjects, it triggers the creation of GameObjects on connected clients. The spawning system manages the lifecycle of the GameObject, and synchronizes the state of the GameObject based on how you set the GameObject up.
|
||||
When you make a single player game In Mirror, you usually use the `GameObject.Instantiate` method to create new game objects at runtime. However, with a multiplayer system, the server itself must “spawn” game objects in order for them to be active within the networked game. When the server spawns game objects, it triggers the creation of game objects on connected clients. The spawning system manages the lifecycle of the game object, and synchronizes the state of the game object based on how you set the game object up.
|
||||
|
||||
For more details about networked instantiating and spawning, see documentation on Spawning GameObjects.
|
||||
For more details about networked instantiating and spawning, see documentation on Spawning game objects.
|
||||
|
||||
## Players and Local Players
|
||||
|
||||
Mirror’s multiplayer HLAPI system handles player GameObjects differently to non-player GameObjects. When a new player joins the game (when a new client connects to the server), that player’s GameObject becomes a “local player” GameObject on the client of that player, and Mirror associates the player’s connection with the player’s GameObject. Mirror associates one player GameObject for each person playing the game, and routes networking commands to that individual GameObject. A player cannot invoke a command on another player’s GameObject, only their own.
|
||||
Mirror’s multiplayer HLAPI system handles player game objects differently to non-player game objects. When a new player joins the game (when a new client connects to the server), that player’s game object becomes a “local player” game object on the client of that player, and Mirror associates the player’s connection with the player’s game object. Mirror associates one player game object for each person playing the game, and routes networking commands to that individual game object. A player cannot invoke a command on another player’s game object, only their own.
|
||||
|
||||
For more details, see documentation on Player GameObjects.
|
||||
For more details, see documentation on Player game objects.
|
||||
|
||||
## Authority
|
||||
|
||||
Servers and clients can both manage a GameObject’s behavior. The concept of “authority” refers to how and where a GameObject is managed. Mirror’s HLAPI is based around “server authority” as the default state, where the Server (the host) has authority over all GameObjects which do not represent players. Player GameObjects are a special case and treated as having “local authority”. You may want to build your game using a different system of authority - for more details, see Network Authority.
|
||||
Servers and clients can both manage a game object’s behavior. The concept of “authority” refers to how and where a game object is managed. Mirror’s HLAPI is based around “server authority” as the default state, where the Server (the host) has authority over all game objects which do not represent players. Player game objects are a special case and treated as having “local authority”. You may want to build your game using a different system of authority - for more details, see Network Authority.
|
||||
|
@ -6,7 +6,7 @@ Mirror uses GUID for Asset Ids. Every prefab with a NetworkIdentity component ha
|
||||
|
||||
## Scene Id
|
||||
|
||||
Mirror uses uint for Scene Ids. Every GameObject with a NetworkIdentity in the scene (hierarchy) is assigned a scene id in OnPostProcessScene. Mirror needs that to distinguish scene objects from each other, because Unity has no unique id for different GameObjects in the scene.
|
||||
Mirror uses uint for Scene Ids. Every game object with a NetworkIdentity in the scene (hierarchy) is assigned a scene id in OnPostProcessScene. Mirror needs that to distinguish scene objects from each other, because Unity has no unique id for different game objects in the scene.
|
||||
|
||||
## Network Instance Id (a.k.a. NetId)
|
||||
|
||||
|
@ -7,14 +7,14 @@ This page contains an overview of the most basic and common things you need when
|
||||
- Networked Player Prefabs (for players to control)
|
||||
- Scripts which are multiplayer-aware
|
||||
|
||||
There are variations on this list; for example, in a multiplayer chess game, or a real-time strategy (RTS) game, you don’t need a visible GameObject to represent the player. However, you might still want an invisible empty GameObject to represent the player, and attach scripts to it which relate to what the player is able to do.
|
||||
There are variations on this list; for example, in a multiplayer chess game, or a real-time strategy (RTS) game, you don’t need a visible game object to represent the player. However, you might still want an invisible empty game object to represent the player, and attach scripts to it which relate to what the player is able to do.
|
||||
|
||||
This introductory page contains a brief description of each of the items listed above. However, each section links to more detailed documentation, which you need to continue reading to fully understand them.
|
||||
|
||||
There are also some important concepts that you need to understand and make choices about when building your game. These concepts can broadly be summarised as:
|
||||
|
||||
- The relationship between a client, a server, and a host
|
||||
- The idea of authority over GameObjects and actions
|
||||
- The idea of authority over game objects and actions
|
||||
|
||||
To learn about these concepts, see documentation on Network System Concepts.
|
||||
|
||||
@ -34,7 +34,7 @@ Mirror has an extremely basic built-in version of such an interface, called the
|
||||
|
||||
To learn more, see documentation on the Network Manager HUD.
|
||||
|
||||
## Networked player GameObjects
|
||||
## Networked player Game Objects
|
||||
|
||||
Most multiplayer games feature some kind of object that a player can control, like a character, a car, or something else. Some multiplayer games don’t feature a single visible player object, and attach all the scripts to it which control what the player can do in your game.
|
||||
|
||||
@ -54,10 +54,10 @@ Writing scripts for a multiplayer game is different to writing scripts for a sin
|
||||
|
||||
For example, the scripts you place on your player Prefab should allow the “owner” of that player instance to control it, but it should not allow other people to control it.
|
||||
|
||||
You need to think about whether the server or the client has authority over what the script does. Sometimes, you want the script to run on both the server and the clients. Other times, you only want the script to run on the server, and you only want the clients to replicate how the GameObjects are moving (for example, in a game in which players pick up collectible GameObjects, the script should only run on the server so that the server can be the authority on the number of GameObjects collected).
|
||||
You need to think about whether the server or the client has authority over what the script does. Sometimes, you want the script to run on both the server and the clients. Other times, you only want the script to run on the server, and you only want the clients to replicate how the game objects are moving (for example, in a game in which players pick up collectible game objects, the script should only run on the server so that the server can be the authority on the number of game objects collected).
|
||||
|
||||
Depending on what your script does, you need to decide which parts of your script should be active in which situations.
|
||||
|
||||
For player GameObjects, each person usually has active control over their own player instance. This means each client has local authority over its own player, and the server accepts what the client tells it about what the player is doing.
|
||||
For player game objects, each person usually has active control over their own player instance. This means each client has local authority over its own player, and the server accepts what the client tells it about what the player is doing.
|
||||
|
||||
For non-player GameObjects, the server usually has authority over what happens (such as whether an item has been collected), and all clients accept what the server tells them about what has happened to that GameObject.
|
||||
For non-player game objects, the server usually has authority over what happens (such as whether an item has been collected), and all clients accept what the server tells them about what has happened to that game object.
|
||||
|
@ -9,7 +9,7 @@ Data is not synchronized in the opposite direction - from remote clients to the
|
||||
- [SyncVars](../Classes/SyncVars)
|
||||
SyncVars are variables of scripts that inherit from NetworkBehaviour, which are synchronized from the server to clients.
|
||||
- [SyncEvents](../Classes/SyncEvent)
|
||||
SyncEvents are networked events like ClientRpc’s, but instead of calling a function on the GameObject, they trigger Events instead.
|
||||
SyncEvents are networked events like ClientRpc’s, but instead of calling a function on the game object, they trigger Events instead.
|
||||
- [SyncLists](../Classes/SyncLists)
|
||||
SyncLists contain lists of values and synchronize data from servers to clients.
|
||||
- [SyncDictionary](../Classes/SyncDictionary)
|
||||
@ -35,7 +35,7 @@ public virtual bool OnSerialize(NetworkWriter writer, bool initialState);
|
||||
public virtual void OnDeSerialize(NetworkReader reader, bool initialState);
|
||||
```
|
||||
|
||||
Use the `initialState` flag to differentiate between the first time a GameObject[](ttps://docs.unity3d.com/Manual/class-GameObject.htmlhttps://docs.unity3d.com/Manual/Glossary.html#GameObject) is serialized and when incremental updates can be sent. The first time a GameObject is sent to a client, it must include a full state snapshot, but subsequent updates can save on bandwidth by including only incremental changes. Note that SyncVar hook functions are not called when `initialState` is true; they are only called for incremental updates.
|
||||
Use the `initialState` flag to differentiate between the first time a game object is serialized and when incremental updates can be sent. The first time a game object is sent to a client, it must include a full state snapshot, but subsequent updates can save on bandwidth by including only incremental changes. Note that SyncVar hook functions are not called when `initialState` is true; they are only called for incremental updates.
|
||||
|
||||
If a class has SyncVars, then implementations of these functions are added automatically to the class, meaning that a class that has SyncVars cannot also have custom serialization functions.
|
||||
|
||||
@ -43,7 +43,7 @@ The `OnSerialize` function should return true to indicate that an update should
|
||||
|
||||
## Serialization Flow
|
||||
|
||||
GameObjects with the Network Identity component attached can have multiple scripts derived from `NetworkBehaviour`. The flow for serializing these GameObjects is:
|
||||
Game objects with the Network Identity component attached can have multiple scripts derived from `NetworkBehaviour`. The flow for serializing these game objects is:
|
||||
|
||||
On the server:
|
||||
|
||||
@ -51,19 +51,19 @@ On the server:
|
||||
- Each SyncVar in a `NetworkBehaviour` script is assigned a bit in the dirty mask.
|
||||
- Changing the value of SyncVars causes the bit for that SyncVar to be set in the dirty mask
|
||||
- Alternatively, calling `SetDirtyBit` writes directly to the dirty mask
|
||||
- NetworkIdentity GameObjects are checked on the server as part of it’s update loop
|
||||
- If any `NetworkBehaviours` on a `NetworkIdentity` are dirty, then an `UpdateVars` packet is created for that GameObject
|
||||
- The `UpdateVars` packet is populated by calling `OnSerialize` on each `NetworkBehaviour` on the GameObject
|
||||
- NetworkIdentity game objects are checked on the server as part of it’s update loop
|
||||
- If any `NetworkBehaviours` on a `NetworkIdentity` are dirty, then an `UpdateVars` packet is created for that game object
|
||||
- The `UpdateVars` packet is populated by calling `OnSerialize` on each `NetworkBehaviour` on the game object
|
||||
- `NetworkBehaviours` that are not dirty write a zero to the packet for their dirty bits
|
||||
- `NetworkBehaviours` that are dirty write their dirty mask, then the values for the SyncVars that have changed
|
||||
- If `OnSerialize` returns true for a `NetworkBehaviour`, the dirty mask is reset for that `NetworkBehaviour` so it does not send again until its value changes.
|
||||
- The `UpdateVars` packet is sent to ready clients that are observing the GameObject
|
||||
- The `UpdateVars` packet is sent to ready clients that are observing the game object
|
||||
|
||||
On the client:
|
||||
|
||||
- an `UpdateVars packet` is received for a GameObject
|
||||
- The `OnDeserialize` function is called for each `NetworkBehaviour` script on the GameObject
|
||||
- Each `NetworkBehaviour` script on the GameObject reads a dirty mask.
|
||||
- an `UpdateVars packet` is received for a game object
|
||||
- The `OnDeserialize` function is called for each `NetworkBehaviour` script on the game object
|
||||
- Each `NetworkBehaviour` script on the game object reads a dirty mask.
|
||||
- If the dirty mask for a `NetworkBehaviour` is zero, the `OnDeserialize` function returns without reading any more
|
||||
- If the dirty mask is non-zero value, then the `OnDeserialize` function reads the values for the SyncVars that correspond to the dirty bits that are set
|
||||
- If there are SyncVar hook functions, those are invoked with the value read from the stream.
|
||||
@ -91,7 +91,7 @@ public override bool OnSerialize(NetworkWriter writer, bool forceAll)
|
||||
{
|
||||
if (forceAll)
|
||||
{
|
||||
// The first time a GameObject is sent to a client, send all the data (and no dirty bits)
|
||||
// The first time a game object is sent to a client, send all the data (and no dirty bits)
|
||||
writer.WritePackedUInt32((uint)this.int1);
|
||||
writer.WritePackedUInt32((uint)this.int2);
|
||||
writer.Write(this.MyString);
|
||||
@ -174,4 +174,4 @@ public override void OnDeserialize(NetworkReader reader, bool initialState)
|
||||
|
||||
If a `NetworkBehaviour` has a base class that also has serialization functions, the base class functions should also be called.
|
||||
|
||||
Note that the `UpdateVar` packets created for GameObject state updates may be aggregated in buffers before being sent to the client, so a single transport layer packet may contain updates for multiple GameObjects.
|
||||
Note that the `UpdateVar` packets created for game object state updates may be aggregated in buffers before being sent to the client, so a single transport layer packet may contain updates for multiple game objects.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Network Visibility
|
||||
|
||||
Multiplayer games use the concept of network visibility to determine which players can see which GameObjects at any given time during gameplay. In a game that has a moving viewpoint and moving GameObjects, it’s common that players cannot see everything that is happening in the game at once.
|
||||
Multiplayer games use the concept of network visibility to determine which players can see which game objects at any given time during gameplay. In a game that has a moving viewpoint and moving game objects, it’s common that players cannot see everything that is happening in the game at once.
|
||||
|
||||
If a particular player, at a certain point in time during gameplay, cannot see most of the other players, non-player characters, or other moving or interactive things in your game, there is usually no need for the host to send information about those things to the player’s client.
|
||||
|
||||
@ -9,35 +9,35 @@ This can benefit your game in two ways:
|
||||
- It reduces the amount of data sent across the network between players. This can help improve the responsiveness of your game, and reduce bandwidth use. The bigger and more complex your multiplayer game, the more important this issue is.
|
||||
- It also helps prevent hacking. Since a player client does not have information about things that can’t be seen, a hack on that player’s computer cannot reveal the information.
|
||||
|
||||
The idea of “visibility” in the context of networking doesn’t necessarily relate to whether GameObjects are directly visible on-screen. Instead, it relates to whether data should or shouldn’t be sent about the GameObject in question to a particular client. Put simply, if a client can’t ‘see’ an GameObject, it does not need to be sent information about that GameObject across the network. Ideally you want to limit the amount of data you are sending across the network to only what is necessary, because sending large amounts of unnecessary data across the network can cause network performance problems.
|
||||
The idea of “visibility” in the context of networking doesn’t necessarily relate to whether game objects are directly visible on-screen. Instead, it relates to whether data should or shouldn’t be sent about the game object in question to a particular client. Put simply, if a client can’t ‘see’ an game object, it does not need to be sent information about that game object across the network. Ideally you want to limit the amount of data you are sending across the network to only what is necessary, because sending large amounts of unnecessary data across the network can cause network performance problems.
|
||||
|
||||
However, it can be also be resource intensive or complex to determine accurately whether a GameObject truly visible to a given player, so it’s often a good idea to use a more simple calculation for the purposes of determining whether a player should be sent networked data about it - i.e. whether it is ‘Network Visible’. The balance you want to achieve when considering this is between the cost of the complexity of the calculation for determining the visibility, and the cost of sending more information than necessary over the network. A very simple way to calculate this is a distance (proximity) check, and Mirror provides a built-in component for this purpose.
|
||||
However, it can be also be resource intensive or complex to determine accurately whether a game object truly visible to a given player, so it’s often a good idea to use a more simple calculation for the purposes of determining whether a player should be sent networked data about it - i.e. whether it is ‘Network Visible’. The balance you want to achieve when considering this is between the cost of the complexity of the calculation for determining the visibility, and the cost of sending more information than necessary over the network. A very simple way to calculate this is a distance (proximity) check, and Mirror provides a built-in component for this purpose.
|
||||
|
||||
## Network Proximity Checker Component
|
||||
|
||||
Mirror’s Network Proximity Checker component is simplest way to implement network visibility for players. It works in conjunction with the physics system to determine whether GameObjects are close enough (that is, “visible” for the purposes of sending network messages in your multiplayer game).
|
||||
Mirror’s Network Proximity Checker component is simplest way to implement network visibility for players. It works in conjunction with the physics system to determine whether game objects are close enough (that is, “visible” for the purposes of sending network messages in your multiplayer game).
|
||||
|
||||
![The Network Proximity Checker component](NetworkProximityCheck.png)
|
||||
|
||||
To use this component, add it to the Prefab of the networked GameObject for which you want to limit network visibility.
|
||||
To use this component, add it to the Prefab of the networked game object for which you want to limit network visibility.
|
||||
|
||||
The Network Proximity Checker has two configurable visibility parameters:
|
||||
|
||||
- Vis Range controls the distance threshold within which the network should consider a GameObject visible to a player.
|
||||
- Vis Update Interval controls how often the distance test is performed. The value is the delay in seconds between checks. This allows you to optimise the check to perform as few tests as possible. The lower the number, the more frequently the updates occur. For slow-moving GameObjects you can set this interval to higher values. For fast-moving GameObjects, you should set it to lower values.
|
||||
- Vis Range controls the distance threshold within which the network should consider a game object visible to a player.
|
||||
- Vis Update Interval controls how often the distance test is performed. The value is the delay in seconds between checks. This allows you to optimise the check to perform as few tests as possible. The lower the number, the more frequently the updates occur. For slow-moving game objects you can set this interval to higher values. For fast-moving game objects, you should set it to lower values.
|
||||
|
||||
You must attach a Collider component to any GameObjects you want to use with the Network Proximity Checker.
|
||||
You must attach a Collider component to any game objects you want to use with the Network Proximity Checker.
|
||||
|
||||
## Network Visibility on Remote Clients
|
||||
|
||||
When a player on a remote client joins a networked game, only GameObjects that are network-visible to the player will be spawned on that remote client. This means that even if the player enters a large world with many networked GameObjects, the game can start quickly because it does not need to spawn every GameObject that exists in the world. Note that this applies to networked GameObjects in your Scene, but does not affect the loading of Assets. Unity still takes time to load the Assets for registered Prefabs and Scene GameObjects.
|
||||
When a player on a remote client joins a networked game, only game objects that are network-visible to the player will be spawned on that remote client. This means that even if the player enters a large world with many networked game objects, the game can start quickly because it does not need to spawn every game object that exists in the world. Note that this applies to networked game objects in your Scene, but does not affect the loading of Assets. Unity still takes time to load the Assets for registered Prefabs and Scene game objects.
|
||||
|
||||
When a player moves within the world, the set of network-visible GameObjects changes. The player’s client is told about these changes as they happen. The ObjectHide message is sent to clients when a GameObject becomes no longer network-visible. By default, Mirror destroys the GameObject when it receives this message. When a GameObject becomes visible, the client receives an ObjectSpawn message, as if Mirror has spawned the GameObject for the first time. By default, the GameObject is instantiated like any other spawned GameObject.
|
||||
When a player moves within the world, the set of network-visible game objects changes. The player’s client is told about these changes as they happen. The ObjectHide message is sent to clients when a game object becomes no longer network-visible. By default, Mirror destroys the game object when it receives this message. When a game object becomes visible, the client receives an ObjectSpawn message, as if Mirror has spawned the game object for the first time. By default, the game object is instantiated like any other spawned game object.
|
||||
|
||||
## Network Visibility on the Host
|
||||
|
||||
The host shares the same Scene as the server, because it acts as both the server and the client to the player hosting the game. For this reason, it cannot destroy GameObjects that are not visible to the local player.
|
||||
The host shares the same Scene as the server, because it acts as both the server and the client to the player hosting the game. For this reason, it cannot destroy game objects that are not visible to the local player.
|
||||
|
||||
Instead, there is the virtual method OnSetLocalVisibility on the NetworkBehaviour class that is invoked. This method is invoked on all `NetworkBehaviour` scripts on GameObjects that change visibility state on the host.
|
||||
Instead, there is the virtual method OnSetLocalVisibility on the NetworkBehaviour class that is invoked. This method is invoked on all `NetworkBehaviour` scripts on game objects that change visibility state on the host.
|
||||
|
||||
The default implementation of `OnSetLocalVisibility` disables or enables all Renderer components on the GameObject. If you want to customize this implementation, you can override the method in your script, and provide a new behavior for how the host (and therefore the local client) should respond when a GameObject becomes network-visible or invisible (such as disabling HUD elements or renderers).
|
||||
The default implementation of `OnSetLocalVisibility` disables or enables all Renderer components on the game object. If you want to customize this implementation, you can override the method in your script, and provide a new behavior for how the host (and therefore the local client) should respond when a game object becomes network-visible or invisible (such as disabling HUD elements or renderers).
|
||||
|
@ -1,29 +1,29 @@
|
||||
# Customizing Network Visibility
|
||||
|
||||
The built-in Network Proximity Checker component is the built-in default component for determining a GameObject’s network visibility. However, this only provides you with a distance-based check. Sometimes you might want to use other kinds of visibility check, such as grid-based rules, line-of-sight tests, navigation path tests, or any other type of test that suits your game.
|
||||
The built-in Network Proximity Checker component is the built-in default component for determining a game object’s network visibility. However, this only provides you with a distance-based check. Sometimes you might want to use other kinds of visibility check, such as grid-based rules, line-of-sight tests, navigation path tests, or any other type of test that suits your game.
|
||||
|
||||
To do this, you can implement your own custom equivalent of the Network Proximity Checker. To do that, you need to understand how the Network Proximity Checker works. See documentation on the in-editor Network Proximity Checker component, and the NetworkProximityChecker API.
|
||||
|
||||
The Network Proximity Checker is implemented using the public visibility interface of Mirror’s HLAPI. Using this same interface, you can implement any kind of visibility rules you desire. Each NetworkIdentity
|
||||
keeps track of the set of players that it is visible to. The players that a NetworkIdentity GameObject is visible to are called the “observers” of the NetworkIdentity.
|
||||
keeps track of the set of players that it is visible to. The players that a NetworkIdentity game object is visible to are called the “observers” of the NetworkIdentity.
|
||||
|
||||
The Network Proximity Checker calls the RebuildObservers method on the Network Identity component at a fixed interval (set using the “Vis Update Interval” value in the inspector), so that the set of network-visible GameObjects for each player is updated as they move around.
|
||||
The Network Proximity Checker calls the RebuildObservers method on the Network Identity component at a fixed interval (set using the “Vis Update Interval” value in the inspector), so that the set of network-visible game objects for each player is updated as they move around.
|
||||
|
||||
On the `NetworkBehaviour`class (which your networked scripts inherit from), there are some virtual functions for determining visibility. These are:
|
||||
|
||||
- **OnCheckObserver**
|
||||
This method is called on the server, on each networked GameObject when a new player enters the game. If it returns true, that player is added to the object’s observers. The `NetworkProximityChecker` method does a simple distance check in its implementation of this function, and uses `Physics.OverlapSphere()` to find the players that are within the visibility distance for this object.
|
||||
This method is called on the server, on each networked game object when a new player enters the game. If it returns true, that player is added to the object’s observers. The `NetworkProximityChecker` method does a simple distance check in its implementation of this function, and uses `Physics.OverlapSphere()` to find the players that are within the visibility distance for this object.
|
||||
|
||||
- **OnRebuildObservers**
|
||||
This method is called on the server when `RebuildObservers` is invoked. This method expects the set of observers to be populated with the players that can see the object. The NetworkServer then handles sending `ObjectHide` and `ObjectSpawn` messages based on the differences between the old and new visibility sets.
|
||||
|
||||
You can check whether any given networked GameObject is a player by checking if its `NetworkIdentity` has a valid connectionToClient. For example:
|
||||
You can check whether any given networked game object is a player by checking if its `NetworkIdentity` has a valid connectionToClient. For example:
|
||||
|
||||
```
|
||||
var hits = Physics.OverlapSphere(transform.position, visRange);
|
||||
foreach (var hit in hits)
|
||||
{
|
||||
// (if a GameObject has a connectionToClient, it is a player)
|
||||
// (if a game object has a connectionToClient, it is a player)
|
||||
var uv = hit.GetComponent<NetworkIdentity>();
|
||||
if (uv != null && uv.connectionToClient != null)
|
||||
observers.Add(uv.connectionToClient);
|
||||
|
@ -4,19 +4,19 @@ This document describes steps to converting a single player game to a multiplaye
|
||||
|
||||
## NetworkManager set-up
|
||||
|
||||
- Add a new GameObject to the Scene and rename it “NetworkManager”.
|
||||
- Add the NetworkManager component to the “NetworkManager” GameObject.
|
||||
- Add the NetworkManagerHUD component to the GameObject. This provides the default UI for managing the network game state.
|
||||
- Add a new game object to the Scene and rename it “NetworkManager”.
|
||||
- Add the NetworkManager component to the “NetworkManager” game object.
|
||||
- Add the NetworkManagerHUD component to the game object. This provides the default UI for managing the network game state.
|
||||
|
||||
See [Using the NetworkManager](/Mirror/Components/NetworkManager).
|
||||
|
||||
## Player Prefab
|
||||
|
||||
- Find the Prefab for the player GameObject in the game, or create a Prefab from the player GameObject
|
||||
- Find the Prefab for the player game object in the game, or create a Prefab from the player game object
|
||||
- Add the NetworkIdentity component to the player Prefab
|
||||
- Check the LocalPlayerAuthority box on the NetworkIdentity
|
||||
- Set the `playerPrefab` in the NetworkManager’s Spawn Info section to the player Prefab
|
||||
- Remove the player GameObject instance from the Scene if it exists in the Scene
|
||||
- Remove the player game object instance from the Scene if it exists in the Scene
|
||||
|
||||
See [Player Objects](/Mirror/Concepts/GameObjects/SpawnPlayer) for more information.
|
||||
|
||||
@ -61,7 +61,7 @@ See [State Synchronization](/Mirror/Concepts/StateSync).
|
||||
|
||||
See [Networked Actions](/Mirror/Concepts/Communications/).
|
||||
|
||||
## Non-player GameObjects
|
||||
## Non-player game objects
|
||||
|
||||
Fix non-player prefabs such as enemies:
|
||||
|
||||
@ -74,9 +74,9 @@ Fix non-player prefabs such as enemies:
|
||||
|
||||
- Potentially change spawner scripts to be NetworkBehaviours
|
||||
- Modify spawners to only run on the server (use isServer property or the `OnStartServer()` function)
|
||||
- Call `NetworkServer.Spawn()` for created GameObjects
|
||||
- Call `NetworkServer.Spawn()` for created game objects
|
||||
|
||||
## Spawn positions for players
|
||||
|
||||
- Add a new GameObject and place it at player’s start location
|
||||
- Add the NetworkStartPosition component to the new GameObject
|
||||
- Add a new game object and place it at player’s start location
|
||||
- Add the NetworkStartPosition component to the new game object
|
||||
|
@ -7,7 +7,7 @@ A common use case for the MultiplexTransport is a server listening to both webso
|
||||
To use the MultiplexTransport follow these steps:
|
||||
|
||||
1. Add a gameobject with a NetworkManager to your scene if you have not done so
|
||||
2. By default, Unity will add TelepathyTransport to your NetworkManager GameObject
|
||||
2. By default, Unity will add TelepathyTransport to your NetworkManager game object
|
||||
3. Add a MultiplexTransport component to the gameobject
|
||||
4. Assign the MultiplexTransport component in your NetworkManager's transport
|
||||
5. Add a WebsocketTransport component to the gameobject
|
||||
|
Loading…
Reference in New Issue
Block a user