2using System.Collections.Generic;
9 public enum ConnectState
24 internal static readonly Dictionary<ushort, NetworkMessageDelegate> handlers =
25 new Dictionary<ushort, NetworkMessageDelegate>();
29 public static readonly Dictionary<uint, NetworkIdentity>
spawned =
30 new Dictionary<uint, NetworkIdentity>();
47 internal static ConnectState connectState = ConnectState.None;
55 public static bool active => connectState == ConnectState.Connecting ||
56 connectState == ConnectState.Connected;
59 public static bool isConnecting => connectState == ConnectState.Connecting;
62 public static bool isConnected => connectState == ConnectState.Connected;
72 public static Action OnConnectedEvent;
73 public static Action OnDisconnectedEvent;
74 public static Action<TransportError, string> OnErrorEvent;
77 public static readonly Dictionary<Guid, GameObject>
prefabs =
78 new Dictionary<Guid, GameObject>();
83 internal static readonly Dictionary<Guid, SpawnHandlerDelegate> spawnHandlers =
84 new Dictionary<Guid, SpawnHandlerDelegate>();
85 internal static readonly Dictionary<Guid, UnSpawnDelegate> unspawnHandlers =
86 new Dictionary<Guid, UnSpawnDelegate>();
90 internal static bool isSpawnFinished;
93 internal static readonly Dictionary<ulong, NetworkIdentity> spawnableObjects =
94 new Dictionary<ulong, NetworkIdentity>();
103 public static bool isLoadingScene;
106 static void AddTransportHandlers()
109 Transport.activeTransport.OnClientConnected += OnTransportConnected;
110 Transport.activeTransport.OnClientDataReceived += OnTransportData;
111 Transport.activeTransport.OnClientDisconnected += OnTransportDisconnected;
112 Transport.activeTransport.OnClientError += OnTransportError;
115 static void RemoveTransportHandlers()
118 Transport.activeTransport.OnClientConnected -= OnTransportConnected;
119 Transport.activeTransport.OnClientDataReceived -= OnTransportData;
120 Transport.activeTransport.OnClientDisconnected -= OnTransportDisconnected;
121 Transport.activeTransport.OnClientError -= OnTransportError;
124 internal static void RegisterSystemHandlers(
bool hostMode)
131 RegisterHandler<ObjectDestroyMessage>(OnHostClientObjectDestroy);
132 RegisterHandler<ObjectHideMessage>(OnHostClientObjectHide);
133 RegisterHandler<NetworkPongMessage>(_ => {},
false);
134 RegisterHandler<SpawnMessage>(OnHostClientSpawn);
136 RegisterHandler<ObjectSpawnStartedMessage>(_ => {});
138 RegisterHandler<ObjectSpawnFinishedMessage>(_ => {});
140 RegisterHandler<EntityStateMessage>(_ => {});
144 RegisterHandler<ObjectDestroyMessage>(OnObjectDestroy);
145 RegisterHandler<ObjectHideMessage>(OnObjectHide);
146 RegisterHandler<NetworkPongMessage>(
NetworkTime.OnClientPong,
false);
147 RegisterHandler<SpawnMessage>(OnSpawn);
148 RegisterHandler<ObjectSpawnStartedMessage>(OnObjectSpawnStarted);
149 RegisterHandler<ObjectSpawnFinishedMessage>(OnObjectSpawnFinished);
150 RegisterHandler<EntityStateMessage>(OnEntityStateMessage);
154 RegisterHandler<ChangeOwnerMessage>(OnChangeOwner);
155 RegisterHandler<RpcMessage>(OnRPCMessage);
163 Debug.Assert(
Transport.
activeTransport !=
null,
"There was no active transport when calling NetworkClient.Connect, If you are calling Connect manually then make sure to set 'Transport.activeTransport' first");
165 RegisterSystemHandlers(
false);
166 Transport.activeTransport.enabled =
true;
167 AddTransportHandlers();
169 connectState = ConnectState.Connecting;
179 Debug.Assert(
Transport.
activeTransport !=
null,
"There was no active transport when calling NetworkClient.Connect, If you are calling Connect manually then make sure to set 'Transport.activeTransport' first");
181 RegisterSystemHandlers(
false);
182 Transport.activeTransport.enabled =
true;
183 AddTransportHandlers();
185 connectState = ConnectState.Connecting;
193 public static void ConnectHost()
197 RegisterSystemHandlers(
true);
199 connectState = ConnectState.Connected;
204 connectionToServer.connectionToClient = connectionToClient;
205 connectionToClient.connectionToServer = connectionToServer;
239 if (connectState != ConnectState.Connecting &&
240 connectState != ConnectState.Connected)
248 connectState = ConnectState.Disconnecting;
261 static void OnTransportConnected()
273 connectState = ConnectState.Connected;
275 OnConnectedEvent?.Invoke();
277 else Debug.LogError(
"Skipped Connect message handling because connection is null.");
281 static bool UnpackAndInvoke(
NetworkReader reader,
int channelId)
286 if (handlers.TryGetValue(msgType, out NetworkMessageDelegate handler))
288 handler.Invoke(
connection, reader, channelId);
293 connection.lastMessageTime = Time.time;
304 Debug.LogWarning($
"Unknown message id: {msgType}. This can happen if no handler was registered for this message.");
313 Debug.LogWarning(
"Invalid message header.");
321 internal static void OnTransportData(ArraySegment<byte> data,
int channelId)
329 if (!unbatcher.AddBatch(data))
331 Debug.LogWarning($
"NetworkClient: failed to add batch, disconnecting.");
346 while (!isLoadingScene &&
347 unbatcher.GetNextMessage(out
NetworkReader reader, out
double remoteTimestamp))
353 connection.remoteTimeStamp = remoteTimestamp;
356 if (!UnpackAndInvoke(reader, channelId))
366 Debug.LogWarning($
"NetworkClient: failed to unpack and invoke message. Disconnecting.");
375 Debug.LogWarning($
"NetworkClient: received Message was too short (messages should start with message id)");
397 if (!isLoadingScene && unbatcher.BatchesCount > 0)
399 Debug.LogError($
"Still had {unbatcher.BatchesCount} batches remaining after processing, even though processing was not interrupted by a scene change. This should never happen, as it would cause ever growing batches.\nPossible reasons:\n* A message didn't deserialize as much as it serialized\n*There was no message handler for a message id, so the reader wasn't read until the end.");
402 else Debug.LogError(
"Skipped Data message handling because connection is null.");
411 internal static void OnTransportDisconnected()
416 if (connectState == ConnectState.Disconnected)
return;
420 if (
connection !=
null) OnDisconnectedEvent?.Invoke();
422 connectState = ConnectState.Disconnected;
432 RemoveTransportHandlers();
436 static void OnTransportError(TransportError error,
string reason)
440 Debug.LogWarning($
"Client Transport Error: {error}: {reason}. This is fine.");
441 OnErrorEvent?.Invoke(error, reason);
451 if (connectState == ConnectState.Connected)
455 else Debug.LogError(
"NetworkClient Send when not connected to a server");
457 else Debug.LogError(
"NetworkClient Send with no connection");
466 if (handlers.ContainsKey(msgType))
468 Debug.LogWarning($
"NetworkClient.RegisterHandler replacing handler for {typeof(T).FullName}, id={msgType}. If replacement is intentional, use ReplaceHandler instead to avoid this warning.");
474 handlers[msgType] =
MessagePacking.WrapHandler((Action<NetworkConnection, T>) HandlerWrapped, requireAuthentication);
480 public static void ReplaceHandler<T>(Action<NetworkConnection, T> handler,
bool requireAuthentication =
true)
484 handlers[msgType] =
MessagePacking.WrapHandler(handler, requireAuthentication);
493 ReplaceHandler((
NetworkConnection _, T value) => { handler(value); }, requireAuthentication);
502 return handlers.Remove(msgType);
508 public static bool GetPrefab(Guid assetId, out GameObject prefab)
511 return assetId != Guid.Empty &&
512 prefabs.TryGetValue(assetId, out prefab) && prefab !=
null;
518 if (prefab.
assetId == Guid.Empty)
520 Debug.LogError($
"Can not Register '{prefab.name}' because it had empty assetid. If this is a scene Object use RegisterSpawnHandler instead");
526 Debug.LogError($
"Can not Register '{prefab.name}' because it has a sceneId, make sure you are passing in the original prefab and not an instance in the scene.");
531 if (identities.Length > 1)
533 Debug.LogError($
"Prefab '{prefab.name}' has multiple NetworkIdentity components. There should only be one NetworkIdentity on a prefab, and it must be on the root object.");
539 Debug.LogWarning($
"Replacing existing prefab with assetId '{prefab.assetId}'. Old prefab '{existingPrefab.name}', New prefab '{prefab.name}'");
542 if (spawnHandlers.ContainsKey(prefab.
assetId) || unspawnHandlers.ContainsKey(prefab.
assetId))
544 Debug.LogWarning($
"Adding prefab '{prefab.name}' with assetId '{prefab.assetId}' when spawnHandlers with same assetId already exists. If you want to use custom spawn handling, then remove the prefab from NetworkManager's registered prefabs first.");
560 Debug.LogError(
"Could not register prefab because it was null");
564 if (newAssetId == Guid.Empty)
566 Debug.LogError($
"Could not register '{prefab.name}' with new assetId because the new assetId was empty");
571 if (identity ==
null)
573 Debug.LogError($
"Could not register '{prefab.name}' since it contains no NetworkIdentity component");
577 if (identity.
assetId != Guid.Empty && identity.
assetId != newAssetId)
579 Debug.LogError($
"Could not register '{prefab.name}' to {newAssetId} because it already had an AssetId, Existing assetId {identity.assetId}");
583 identity.assetId = newAssetId;
585 RegisterPrefabIdentity(identity);
593 Debug.LogError(
"Could not register prefab because it was null");
598 if (identity ==
null)
600 Debug.LogError($
"Could not register '{prefab.name}' since it contains no NetworkIdentity component");
604 RegisterPrefabIdentity(identity);
612 public static void RegisterPrefab(GameObject prefab, Guid newAssetId, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
615 if (spawnHandler ==
null)
617 Debug.LogError($
"Can not Register null SpawnHandler for {newAssetId}");
621 RegisterPrefab(prefab, newAssetId, msg => spawnHandler(msg.position, msg.assetId), unspawnHandler);
626 public static void RegisterPrefab(GameObject prefab, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
630 Debug.LogError(
"Could not register handler for prefab because the prefab was null");
635 if (identity ==
null)
637 Debug.LogError($
"Could not register handler for '{prefab.name}' since it contains no NetworkIdentity component");
643 Debug.LogError($
"Can not Register '{prefab.name}' because it has a sceneId, make sure you are passing in the original prefab and not an instance in the scene.");
647 Guid assetId = identity.
assetId;
649 if (assetId == Guid.Empty)
651 Debug.LogError($
"Can not Register handler for '{prefab.name}' because it had empty assetid. If this is a scene Object use RegisterSpawnHandler instead");
656 if (spawnHandler ==
null)
658 Debug.LogError($
"Can not Register null SpawnHandler for {assetId}");
662 RegisterPrefab(prefab, msg => spawnHandler(msg.position, msg.assetId), unspawnHandler);
670 public static void RegisterPrefab(GameObject prefab, Guid newAssetId, SpawnHandlerDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
672 if (newAssetId == Guid.Empty)
674 Debug.LogError($
"Could not register handler for '{prefab.name}' with new assetId because the new assetId was empty");
680 Debug.LogError(
"Could not register handler for prefab because the prefab was null");
685 if (identity ==
null)
687 Debug.LogError($
"Could not register handler for '{prefab.name}' since it contains no NetworkIdentity component");
691 if (identity.
assetId != Guid.Empty && identity.
assetId != newAssetId)
693 Debug.LogError($
"Could not register Handler for '{prefab.name}' to {newAssetId} because it already had an AssetId, Existing assetId {identity.assetId}");
699 Debug.LogError($
"Can not Register '{prefab.name}' because it has a sceneId, make sure you are passing in the original prefab and not an instance in the scene.");
703 identity.assetId = newAssetId;
704 Guid assetId = identity.
assetId;
706 if (spawnHandler ==
null)
708 Debug.LogError($
"Can not Register null SpawnHandler for {assetId}");
712 if (unspawnHandler ==
null)
714 Debug.LogError($
"Can not Register null UnSpawnHandler for {assetId}");
718 if (spawnHandlers.ContainsKey(assetId) || unspawnHandlers.ContainsKey(assetId))
720 Debug.LogWarning($
"Replacing existing spawnHandlers for prefab '{prefab.name}' with assetId '{assetId}'");
723 if (
prefabs.ContainsKey(assetId))
726 Debug.LogError($
"assetId '{assetId}' is already used by prefab '{prefabs[assetId].name}', unregister the prefab first before trying to add handler");
730 if (identities.Length > 1)
732 Debug.LogError($
"Prefab '{prefab.name}' has multiple NetworkIdentity components. There should only be one NetworkIdentity on a prefab, and it must be on the root object.");
737 spawnHandlers[assetId] = spawnHandler;
738 unspawnHandlers[assetId] = unspawnHandler;
743 public static void RegisterPrefab(GameObject prefab, SpawnHandlerDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
747 Debug.LogError(
"Could not register handler for prefab because the prefab was null");
752 if (identity ==
null)
754 Debug.LogError($
"Could not register handler for '{prefab.name}' since it contains no NetworkIdentity component");
760 Debug.LogError($
"Can not Register '{prefab.name}' because it has a sceneId, make sure you are passing in the original prefab and not an instance in the scene.");
764 Guid assetId = identity.
assetId;
766 if (assetId == Guid.Empty)
768 Debug.LogError($
"Can not Register handler for '{prefab.name}' because it had empty assetid. If this is a scene Object use RegisterSpawnHandler instead");
772 if (spawnHandler ==
null)
774 Debug.LogError($
"Can not Register null SpawnHandler for {assetId}");
778 if (unspawnHandler ==
null)
780 Debug.LogError($
"Can not Register null UnSpawnHandler for {assetId}");
784 if (spawnHandlers.ContainsKey(assetId) || unspawnHandlers.ContainsKey(assetId))
786 Debug.LogWarning($
"Replacing existing spawnHandlers for prefab '{prefab.name}' with assetId '{assetId}'");
789 if (
prefabs.ContainsKey(assetId))
792 Debug.LogError($
"assetId '{assetId}' is already used by prefab '{prefabs[assetId].name}', unregister the prefab first before trying to add handler");
796 if (identities.Length > 1)
798 Debug.LogError($
"Prefab '{prefab.name}' has multiple NetworkIdentity components. There should only be one NetworkIdentity on a prefab, and it must be on the root object.");
803 spawnHandlers[assetId] = spawnHandler;
804 unspawnHandlers[assetId] = unspawnHandler;
812 Debug.LogError(
"Could not unregister prefab because it was null");
817 if (identity ==
null)
819 Debug.LogError($
"Could not unregister '{prefab.name}' since it contains no NetworkIdentity component");
823 Guid assetId = identity.
assetId;
826 spawnHandlers.Remove(assetId);
827 unspawnHandlers.Remove(assetId);
837 public static void RegisterSpawnHandler(Guid assetId, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
840 if (spawnHandler ==
null)
842 Debug.LogError($
"Can not Register null SpawnHandler for {assetId}");
855 public static void RegisterSpawnHandler(Guid assetId, SpawnHandlerDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
857 if (spawnHandler ==
null)
859 Debug.LogError($
"Can not Register null SpawnHandler for {assetId}");
863 if (unspawnHandler ==
null)
865 Debug.LogError($
"Can not Register null UnSpawnHandler for {assetId}");
869 if (assetId == Guid.Empty)
871 Debug.LogError(
"Can not Register SpawnHandler for empty Guid");
875 if (spawnHandlers.ContainsKey(assetId) || unspawnHandlers.ContainsKey(assetId))
877 Debug.LogWarning($
"Replacing existing spawnHandlers for {assetId}");
880 if (
prefabs.ContainsKey(assetId))
883 Debug.LogError($
"assetId '{assetId}' is already used by prefab '{prefabs[assetId].name}'");
888 spawnHandlers[assetId] = spawnHandler;
889 unspawnHandlers[assetId] = unspawnHandler;
895 spawnHandlers.Remove(assetId);
896 unspawnHandlers.Remove(assetId);
903 spawnHandlers.Clear();
904 unspawnHandlers.Clear();
907 internal static bool InvokeUnSpawnHandler(Guid assetId, GameObject obj)
909 if (unspawnHandlers.TryGetValue(assetId, out UnSpawnDelegate handler) && handler !=
null)
928 Debug.LogError(
"NetworkClient is already ready. It shouldn't be called twice.");
935 Debug.LogError(
"Ready() called with invalid connection object: conn=null");
943 connection.isReady =
true;
968 connection.identity = identity;
970 else Debug.LogWarning(
"No ready connection found for setting player controller during InternalAddPlayer");
979 Debug.LogError(
"AddPlayer requires a valid NetworkClient.connection.");
987 Debug.LogError(
"AddPlayer requires a ready NetworkClient.");
993 Debug.LogError(
"NetworkClient.AddPlayer: a PlayerController was already added. Did you call AddPlayer twice?");
1005 if (message.assetId != Guid.Empty)
1006 identity.assetId = message.assetId;
1008 if (!identity.gameObject.activeSelf)
1010 identity.gameObject.SetActive(
true);
1014 identity.transform.localPosition = message.position;
1015 identity.transform.localRotation = message.rotation;
1016 identity.transform.localScale = message.scale;
1017 identity.hasAuthority = message.isOwner;
1018 identity.netId = message.netId;
1020 if (message.isLocalPlayer)
1021 InternalAddPlayer(identity);
1025 if (message.payload.Count > 0)
1029 identity.OnDeserializeAllSafely(payloadReader,
true);
1033 spawned[message.netId] = identity;
1041 if (isSpawnFinished)
1043 identity.NotifyAuthority();
1044 identity.OnStartClient();
1045 CheckForLocalPlayer(identity);
1053 identity = GetExistingObject(message.netId);
1056 if (identity !=
null)
1061 if (message.assetId == Guid.Empty && message.sceneId == 0)
1063 Debug.LogError($
"OnSpawn message with netId '{message.netId}' has no AssetId or sceneId");
1067 identity = message.sceneId == 0 ? SpawnPrefab(message) : SpawnSceneObject(message.sceneId);
1069 if (identity ==
null)
1071 Debug.LogError($
"Could not spawn assetId={message.assetId} scene={message.sceneId:X} netId={message.netId}");
1093 if (spawnHandlers.TryGetValue(message.assetId, out SpawnHandlerDelegate handler))
1095 GameObject obj = handler(message);
1098 Debug.LogError($
"Spawn Handler returned null, Handler assetId '{message.assetId}'");
1102 if (identity ==
null)
1104 Debug.LogError($
"Object Spawned by handler did not have a NetworkIdentity, Handler assetId '{message.assetId}'");
1111 if (
GetPrefab(message.assetId, out GameObject prefab))
1113 GameObject obj = GameObject.Instantiate(prefab, message.position, message.rotation);
1118 Debug.LogError($
"Failed to spawn server object, did you forget to add it to the NetworkManager? assetId={message.assetId} netId={message.netId}");
1125 if (identity ==
null)
1127 Debug.LogError($
"Spawn scene object not found for {sceneId:X}. Make sure that client and server use exactly the same project. This only happens if the hierarchy gets out of sync.");
1139 if (spawnableObjects.TryGetValue(sceneId, out
NetworkIdentity identity))
1141 spawnableObjects.Remove(sceneId);
1151 return !identity.gameObject.activeSelf &&
1152 identity.gameObject.hideFlags != HideFlags.NotEditable &&
1153 identity.gameObject.hideFlags != HideFlags.HideAndDontSave &&
1154 identity.sceneId != 0;
1161 spawnableObjects.Clear();
1168 if (ConsiderForSpawning(identity))
1170 if (spawnableObjects.TryGetValue(identity.sceneId, out
NetworkIdentity existingIdentity))
1172 string msg = $
"NetworkClient: Duplicate sceneId {identity.sceneId} detected on {identity.gameObject.name} and {existingIdentity.gameObject.name}\n" +
1173 $
"This can happen if a networked object is persisted in DontDestroyOnLoad through loading / changing to the scene where it originated,\n" +
1174 $
"otherwise you may need to open and re-save the {identity.gameObject.scene} to reset scene id's.";
1175 Debug.LogWarning(msg, identity.gameObject);
1179 spawnableObjects.Add(identity.sceneId, identity);
1189 isSpawnFinished =
false;
1195 ClearNullFromSpawned();
1202 identity.NotifyAuthority();
1203 identity.OnStartClient();
1204 CheckForLocalPlayer(identity);
1206 isSpawnFinished =
true;
1209 static readonly List<uint> removeFromSpawned =
new List<uint>();
1210 static void ClearNullFromSpawned()
1217 foreach (KeyValuePair<uint, NetworkIdentity> kvp
in spawned)
1219 if (kvp.Value ==
null)
1221 removeFromSpawned.Add(kvp.Key);
1226 foreach (uint
id in removeFromSpawned)
1230 removeFromSpawned.Clear();
1237 spawned.Remove(message.netId);
1244 localObject !=
null)
1247 aoi.SetHostVisibility(localObject,
false);
1251 internal static void OnHostClientSpawn(
SpawnMessage message)
1257 spawned[message.netId] = localObject;
1260 if (message.isLocalPlayer)
1261 InternalAddPlayer(localObject);
1263 localObject.hasAuthority = message.isOwner;
1264 localObject.NotifyAuthority();
1265 localObject.OnStartClient();
1268 aoi.SetHostVisibility(localObject,
true);
1270 CheckForLocalPlayer(localObject);
1281 localObject.OnDeserializeAllSafely(networkReader,
false);
1283 else Debug.LogWarning($
"Did not find target for sync message for {message.netId} . Note: this can be completely normal because UDP messages may arrive out of order, so this message might have arrived after a Destroy message.");
1292 identity.HandleRemoteCall(message.componentIndex, message.functionHash, RemoteCallType.ClientRpc, networkReader);
1296 static void OnObjectHide(
ObjectHideMessage message) => DestroyObject(message.netId);
1298 internal static void OnObjectDestroy(
ObjectDestroyMessage message) => DestroyObject(message.netId);
1305 ApplySpawnPayload(identity, message);
1313 if (identity !=
null)
1314 ChangeOwner(identity, message);
1316 Debug.LogError($
"OnChangeOwner: Could not find object with netId {message.netId}");
1327 identity.OnStopLocalPlayer();
1331 identity.hasAuthority = message.isOwner;
1332 identity.NotifyAuthority();
1335 identity.isLocalPlayer = message.isLocalPlayer;
1350 CheckForLocalPlayer(identity);
1360 identity.OnStartLocalPlayer();
1366 static void DestroyObject(uint netId)
1371 if (localObject.isLocalPlayer)
1372 localObject.OnStopLocalPlayer();
1374 localObject.OnStopClient();
1377 if (InvokeUnSpawnHandler(localObject.assetId, localObject.gameObject))
1380 localObject.Reset();
1383 else if (localObject.sceneId == 0)
1386 GameObject.Destroy(localObject.gameObject);
1391 localObject.gameObject.SetActive(
false);
1392 spawnableObjects[localObject.sceneId] = localObject;
1394 localObject.Reset();
1406 internal static void NetworkEarlyUpdate()
1415 internal static void NetworkLateUpdate()
1420 localConnection.Update();
1426 if (
active && connectState == ConnectState.Connected)
1432 remoteConnection.Update();
1453 if (identity !=
null && identity.gameObject !=
null)
1456 identity.OnStopLocalPlayer();
1458 identity.OnStopClient();
1468 bool shouldDestroy = !identity.isServer || hostOwned;
1471 bool wasUnspawned = InvokeUnSpawnHandler(identity.
assetId, identity.gameObject);
1486 identity.gameObject.SetActive(
false);
1491 GameObject.Destroy(identity.gameObject);
1499 catch (InvalidOperationException e)
1501 Debug.LogException(e);
1502 Debug.LogError(
"Could not DestroyAllClientObjects because spawned list was modified during loop, make sure you are not modifying NetworkIdentity.spawned by calling NetworkServer.Destroy or NetworkServer.Spawn in OnDestroy or OnDisable.");
1508 [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
1523 spawnableObjects.Clear();
1541 connectState = ConnectState.None;
1545 isSpawnFinished =
false;
1546 isLoadingScene =
false;
1552 OnConnectedEvent =
null;
1553 OnDisconnectedEvent =
null;
1554 OnErrorEvent =
null;
NetworkClient with connection to server.
static bool active
active is true while a client is connecting/connected
static void ClearSpawners()
This clears the registered spawn prefabs and spawn handler functions for this client.
static void RegisterPrefab(GameObject prefab, Guid newAssetId, SpawnHandlerDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
Register a spawnable prefab with custom assetId and custom spawn/unspawn handlers.
static bool isHostClient
True if client is running in host mode.
static void RegisterSpawnHandler(Guid assetId, SpawnHandlerDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
This is an advanced spawning function that registers a custom assetId with the spawning system.
static void RegisterPrefab(GameObject prefab, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
Register a spawnable prefab with custom spawn/unspawn handlers.
static void DestroyAllClientObjects()
Destroys all networked objects on the client.
static void Connect(string address)
Connect client to a NetworkServer by address.
static void ConnectLocalServer()
Connect host mode
static bool GetPrefab(Guid assetId, out GameObject prefab)
Find the registered prefab for this asset id.
static void UnregisterPrefab(GameObject prefab)
Removes a registered spawn prefab that was setup with NetworkClient.RegisterPrefab.
static void Send< T >(T message, int channelId=Channels.Reliable)
Send a NetworkMessage to the server over the given channel.
static readonly Dictionary< Guid, GameObject > prefabs
Registered spawnable prefabs by assetId.
static bool ready
True if client is ready (= joined world).
static readonly Dictionary< uint, NetworkIdentity > spawned
All spawned NetworkIdentities by netId.
static bool isConnecting
Check if client is connecting (before connected).
static void Connect(Uri uri)
Connect client to a NetworkServer by Uri.
static void RegisterPrefab(GameObject prefab)
Register spawnable prefab.
static void ReplaceHandler< T >(Action< NetworkConnection, T > handler, bool requireAuthentication=true)
Replace a handler for a particular message type. Should require authentication by default.
static void RegisterPrefab(GameObject prefab, Guid newAssetId)
Register spawnable prefab with custom assetId.
static void Shutdown()
Shutdown the client.
static void PrepareToSpawnSceneObjects()
Call this after loading/unloading a scene in the client after connection to register the spawnable ob...
static bool Ready()
Sends Ready message to server, indicating that we loaded the scene, ready to enter the game.
static void RegisterPrefab(GameObject prefab, Guid newAssetId, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
Register a spawnable prefab with custom assetId and custom spawn/unspawn handlers.
static void Disconnect()
Disconnect from server.
static bool AddPlayer()
Sends AddPlayer message to the server, indicating that we want to join the world.
static void RegisterHandler< T >(Action< T > handler, bool requireAuthentication=true)
Register a handler for a message type T. Most should require authentication.
static bool UnregisterHandler< T >()
Unregister a message handler of type T.
static bool isConnected
Check if client is connected (after connecting).
static string serverIp
IP address of the connection to server.
static void UnregisterSpawnHandler(Guid assetId)
Removes a registered spawn handler function that was registered with NetworkClient....
static NetworkConnection connection
Client's NetworkConnection to server.
static void RegisterSpawnHandler(Guid assetId, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
This is an advanced spawning function that registers a custom assetId with the spawning system.
static void RegisterPrefab(GameObject prefab, SpawnHandlerDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
Register a spawnable prefab with custom spawn/unspawn handlers.
static NetworkIdentity localPlayer
NetworkIdentity of the localPlayer
Base NetworkConnection class for server-to-client and client-to-server connection.
NetworkIdentity identity
This connection's main object (usually the player object).
abstract string address
IP address of the connection. Can be useful for game master IP bans etc.
abstract void Disconnect()
Disconnects this connection.
NetworkIdentity identifies objects across the network.
Guid assetId
Prefab GUID used to spawn prefabs across the network.
ulong sceneId
Unique identifier for NetworkIdentity objects within a scene, used for spawning scene objects.
bool isLocalPlayer
Return true if this object represents the player on the local machine.
Network Reader for most simple types like floats, ints, buffers, structs, etc. Use NetworkReaderPool....
Pool of NetworkReaders to avoid allocations.
static NetworkReaderPooled Get(byte[] bytes)
Get the next reader in the pool. If pool is empty, creates a new Reader
Pooled NetworkReader, automatically returned to pool when using 'using'
NetworkServer handles remote connections and has a local connection for a local client.
static NetworkConnectionToClient localConnection
Connection to host mode client (if any)
static readonly Dictionary< uint, NetworkIdentity > spawned
All spawned NetworkIdentities by netId.
Synchronizes server time to clients.
Abstract transport layer component
virtual void ClientEarlyUpdate()
NetworkLoop NetworkEarly/LateUpdate were added for a proper network update order. the goal is to: pro...
static Transport activeTransport
The current transport used by Mirror.
abstract void ClientConnect(string address)
Connects the client to the server at the address.
abstract void ClientDisconnect()
Disconnects the client from the server