유니티 Netcode for GameObject, NetworkManager

NetworkManager은 NGO에 관련한 모든 세팅에 대한 것을 가지고 있는 컴포넌트입니다!

즉,  "Central Netcode Hub"라고 부를 수 있겠네요!!

 

NetworkManager인스펙터엔 다양한 프로퍼티가 존재합니다!

https://docs-multiplayer.unity3d.com/netcode/current/components/networkmanager#networkmanager-inspector-properties

 

NetworkManager | Unity Multiplayer Networking

The NetworkManager is a required Netcode for GameObjects (Netcode) component that has all of your project's netcode related settings. Think of it as the "central netcode hub" for your netcode enabled project.

docs-multiplayer.unity3d.com

참고,,,


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는 아래와 같은 방법으로 얻을 수 있습니다!

 

  1. NetworkManager.ConnectedClients Dictionary를 이용해 Key와 Value로 id를 얻기
  2. NetworkManager.ConnectedClientsList를 통해 NetworkClients의 리스트 읽기
  3. NetworkManager.ConnectedClientsIds를 통해 접근할 수 있는 모든 연결된 클라이언트의 id 리스트 얻기
  4. NetworkManager.OnClientConnected 이벤트에 등록된 클라이언트 id얻기
  5. 플레이어의 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);
    }
}