NetworkManager은 NGO에 관련한 모든 세팅에 대한 것을 가지고 있는 컴포넌트입니다!
즉, "Central Netcode Hub"라고 부를 수 있겠네요!!
NetworkManager인스펙터엔 다양한 프로퍼티가 존재합니다!
참고,,,
Connecting
<Unity Transport>컴포넌트의 IP와 Port를 사용해서 NetworkManager에 클라이언트로 접속할 때는
UnityTrasnport에 접근 후 UnityTransport.SetConnectionData 함수를 사용하여 IP주소나 Port 넘버를 세팅할 수 있습니다!
SetConnectionData 함수를 통해 현재 접속중인 Connection Data의 Info를 얻을 수 있습니다!
반대로 <Unity Relay>를 사용하게 되면 SetConnectionData 를 사용하진 못하지만 SetHostRelayData를 사용하거나 SetClientRelayData를 사용하면 됩니다!
Disconnecting and Shutting Down
연결해제에서 알아두어야 할 점은
NetworkManager의 작동이 멈추면 모든 서브시스템에 접근할 수 없다는 점입니다!
public void Disconnect()
{
NetworkManager.Singleton.Shutdown();
}
Disconnecting Clients (Server Only)
서버권한을 가지고 있는 쪽에서 클라이언트의 연결을 끊을 수 있습니다
연결을 끊는데에는 다양한 이유가 있습니다!
연결을 끊기 위해서는 client의 id를 알아야하는데 id는 아래와 같은 방법으로 얻을 수 있습니다!
- NetworkManager.ConnectedClients Dictionary를 이용해 Key와 Value로 id를 얻기
- NetworkManager.ConnectedClientsList를 통해 NetworkClients의 리스트 읽기
- NetworkManager.ConnectedClientsIds를 통해 접근할 수 있는 모든 연결된 클라이언트의 id 리스트 얻기
- NetworkManager.OnClientConnected 이벤트에 등록된 클라이언트 id얻기
- 플레이어의 NetworkObject의 NetworkObject.OwnerClientId얻기...
그리하여 얻은 클라이언트의 id를 이용해
void DisconnectPlayer(NetworkObject player)
{
// Note: If a client invokes this method, it will throw an exception.
NetworkManager.DisconnectClient(player.OwnerClientId);
}
연결을 해제할 수 있습니다!
연결이 해제된 클라이언트는 등록한 NetworkManager.OnClientDisconnectCallback을 통해 연결이 끊김을 알림 받습니다!
Connection Notification Manager Example
다음 예제는 클라이언트가 연결되거나 연결이 끊길 때 알람을 받을 수 있는 방법입니다!
using System;
using UnityEngine;
using Unity.Netcode;
/// <summary>
/// Only attach this example component to the NetworkManager GameObject.
/// This will provide you with a single location to register for client
/// connect and disconnect events.
/// </summary>
public class ConnectionNotificationManager : MonoBehaviour
{
public static ConnectionNotificationManager Singleton { get; internal set; }
public enum ConnectionStatus
{
Connected,
Disconnected
}
/// <summary>
/// This action is invoked whenever a client connects or disconnects from the game.
/// The first parameter is the ID of the client (ulong).
/// The second parameter is whether that client is connecting or disconnecting.
/// </summary>
public event Action<ulong, ConnectionStatus> OnClientConnectionNotification;
private void Awake()
{
if (Singleton != null)
{
// As long as you aren't creating multiple NetworkManager instances, throw an exception.
// (***the current position of the callstack will stop here***)
throw new Exception($"Detected more than one instance of {nameof(ConnectionNotificationManager)}! " +
$"Do you have more than one component attached to a {nameof(GameObject)}");
}
Singleton = this;
}
private void Start()
{
if (Singleton != this){
return; // so things don't get even more broken if this is a duplicate >:(
}
if (NetworkManager.Singleton == null)
{
// Can't listen to something that doesn't exist >:(
throw new Exception($"There is no {nameof(NetworkManager)} for the {nameof(ConnectionNotificationManager)} to do stuff with! " +
$"Please add a {nameof(NetworkManager)} to the scene.");
}
NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnectedCallback;
NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnectCallback;
}
private void OnDestroy()
{
// Since the NetworkManager can potentially be destroyed before this component, only
// remove the subscriptions if that singleton still exists.
if (NetworkManager.Singleton != null)
{
NetworkManager.Singleton.OnClientConnectedCallback -= OnClientConnectedCallback;
NetworkManager.Singleton.OnClientDisconnectCallback -= OnClientDisconnectCallback;
}
}
private void OnClientConnectedCallback(ulong clientId)
{
OnClientConnectionNotification?.Invoke(clientId, ConnectionStatus.Connected);
}
private void OnClientDisconnectCallback(ulong clientId)
{
OnClientConnectionNotification?.Invoke(clientId, ConnectionStatus.Disconnected);
}
}