Version: 2020.1
Unity의 고급 레벨 API를 사용한 통합
일반적인 오류

NetworkTransport를 사용한 통합

Unity 멀티플레이어 서비스를 통합할 때 최대한의 유연성이 필요할 경우 NetworkTransport 클래스를 직접 사용할 수 있습니다. 이 메서드는 더 많은 코드가 필요하지만, 게임이 멀티플레이어 서비스와 통합되는 방법을 보다 세부적으로 제어할 수 있습니다.

다음은 NetworkTransport 클래스를 사용하여 직접 연결할 수 있는 방법에 대한 예제입니다.

using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.Types;
using UnityEngine.Networking.Match;
using System.Collections.Generic;

public class DirectSetup : MonoBehaviour
{
    // Matchmaker related
    List<MatchInfoSnapshot> m_MatchList = new List<MatchInfoSnapshot>();
    bool m_MatchCreated;
    bool m_MatchJoined;
    MatchInfo m_MatchInfo;
    string m_MatchName = "NewRoom";
    NetworkMatch m_NetworkMatch;

    // Connection/communication related
    int m_HostId = -1;
    // On the server there will be multiple connections, on the client this will only contain one ID
    List<int> m_ConnectionIds = new List<int>();
    byte[] m_ReceiveBuffer;
    string m_NetworkMessage = "Hello world";
    string m_LastReceivedMessage = "";
    NetworkWriter m_Writer;
    NetworkReader m_Reader;
    bool m_ConnectionEstablished;

    const int k_ServerPort = 25000;
    const int k_MaxMessageSize = 65535;

    void Awake()
    {
        m_NetworkMatch = gameObject.AddComponent<NetworkMatch>();
    }

    void Start()
    {
        m_ReceiveBuffer = new byte[k_MaxMessageSize];
        m_Writer = new NetworkWriter();
        // While testing with multiple standalone players on one machine this will need to be enabled
        Application.runInBackground = true;
    }

    void OnApplicationQuit()
    {
        NetworkTransport.Shutdown();
    }

    void OnGUI()
    {
        if (string.IsNullOrEmpty(Application.cloudProjectId))
            GUILayout.Label("You must set up the project first. See the Multiplayer tab in the Service Window");
        else
            GUILayout.Label("Cloud Project ID: " + Application.cloudProjectId);

        if (m_MatchJoined)
            GUILayout.Label("Match joined '" + m_MatchName + "' on Matchmaker server");
        else if (m_MatchCreated)
            GUILayout.Label("Match '" + m_MatchName + "' created on Matchmaker server");

        GUILayout.Label("Connection Established: " + m_ConnectionEstablished);

        if (m_MatchCreated || m_MatchJoined)
        {
            GUILayout.Label("Relay Server: " + m_MatchInfo.address + ":" + m_MatchInfo.port);
            GUILayout.Label("NetworkID: " + m_MatchInfo.networkId + " NodeID: " + m_MatchInfo.nodeId);
            GUILayout.BeginHorizontal();
            GUILayout.Label("Outgoing message:");
            m_NetworkMessage = GUILayout.TextField(m_NetworkMessage);
            GUILayout.EndHorizontal();
            GUILayout.Label("Last incoming message: " + m_LastReceivedMessage);

            if (m_ConnectionEstablished && GUILayout.Button("Send message"))
            {
                m_Writer.SeekZero();
                m_Writer.Write(m_NetworkMessage);
                byte error;
                for (int i = 0; i < m_ConnectionIds.Count; ++i)
                {
                    NetworkTransport.Send(m_HostId,
                        m_ConnectionIds[i], 0, m_Writer.AsArray(), m_Writer.Position, out error);
                    if ((NetworkError)error != NetworkError.Ok)
                        Debug.LogError("Failed to send message: " + (NetworkError)error);
                }
            }

            if (GUILayout.Button("Shutdown"))
            {
                m_NetworkMatch.DropConnection(m_MatchInfo.networkId,
                    m_MatchInfo.nodeId, 0, OnConnectionDropped);
            }
        }
        else
        {
            if (GUILayout.Button("Create Room"))
            {
                m_NetworkMatch.CreateMatch(m_MatchName, 4, true, "", "", "", 0, 0, OnMatchCreate);
            }

            if (GUILayout.Button("Join first found match"))
            {
                m_NetworkMatch.ListMatches(0, 1, "", true, 0, 0, (success, info, matches) =>
                {
                    if (success && matches.Count > 0)
                        m_NetworkMatch.JoinMatch(matches[0].networkId, "", "", "", 0, 0, OnMatchJoined);
                });
            }

            if (GUILayout.Button("List rooms"))
            {
                m_NetworkMatch.ListMatches(0, 20, "", true, 0, 0, OnMatchList);
            }

            if (m_MatchList.Count > 0)
            {
                GUILayout.Label("Current rooms:");
            }
            foreach (var match in m_MatchList)
            {
                if (GUILayout.Button(match.name))
                {
                    m_NetworkMatch.JoinMatch(match.networkId, "", "", "", 0, 0, OnMatchJoined);
                }
            }
        }
    }

    public void OnConnectionDropped(bool success, string extendedInfo)
    {
        Debug.Log("Connection has been dropped on matchmaker server");
        NetworkTransport.Shutdown();
        m_HostId = -1;
        m_ConnectionIds.Clear();
        m_MatchInfo = null;
        m_MatchCreated = false;
        m_MatchJoined = false;
        m_ConnectionEstablished = false;
    }

    public virtual void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
    {
        if (success)
        {
            Debug.Log("Create match succeeded");
            Utility.SetAccessTokenForNetwork(matchInfo.networkId, matchInfo.accessToken);
           
            m_MatchCreated = true;
            m_MatchInfo = matchInfo;

            StartServer(matchInfo.address, matchInfo.port, matchInfo.networkId,
                matchInfo.nodeId);
        }
        else
        {
            Debug.LogError("Create match failed: " + extendedInfo);
        }
    }

    public void OnMatchList(bool success, string extendedInfo, List<MatchInfoSnapshot> matches)
    {
        if (success && matches != null)
        {
            m_MatchList = matches;
        }
    else if(!success)
    {
        Debug.LogError("List match failed: " + extendedInfo);
    }
    }

    // When we've joined a match we connect to the server/host
    public virtual void OnMatchJoined(bool success, string extendedInfo, MatchInfo matchInfo)
    {
        if (success)
        {
            Debug.Log("Join match succeeded");
            Utility.SetAccessTokenForNetwork(matchInfo.networkId, matchInfo.accessToken);

            m_MatchJoined = true;
            m_MatchInfo = matchInfo;

            Debug.Log("Connecting to Address:" + matchInfo.address +
                " Port:" + matchInfo.port +
                " NetworKID: " + matchInfo.networkId +
                " NodeID: " + matchInfo.nodeId);
            ConnectThroughRelay(matchInfo.address, matchInfo.port, matchInfo.networkId,
                matchInfo.nodeId);
        }
        else
        {
            Debug.LogError("Join match failed: " + extendedInfo);
        }
    }

    void SetupHost(bool isServer)
    {
        Debug.Log("Initializing network transport");
        NetworkTransport.Init();
        var config = new ConnectionConfig();
        config.AddChannel(QosType.Reliable);
        config.AddChannel(QosType.Unreliable);
        var topology = new HostTopology(config, 4);
        if (isServer)
            m_HostId = NetworkTransport.AddHost(topology, k_ServerPort);
        else
            m_HostId = NetworkTransport.AddHost(topology);
    }

    void StartServer(string relayIp, int relayPort, NetworkID networkId, NodeID nodeId)
    {
        SetupHost(true);

        byte error;
        NetworkTransport.ConnectAsNetworkHost(
            m_HostId, relayIp, relayPort, networkId, Utility.GetSourceID(), nodeId, out error);
    }

    void ConnectThroughRelay(string relayIp, int relayPort, NetworkID networkId, NodeID nodeId)
    {
        SetupHost(false);

        byte error;
        NetworkTransport.ConnectToNetworkPeer(
            m_HostId, relayIp, relayPort, 0, 0, networkId, Utility.GetSourceID(), nodeId, out error);
    }

    void Update()
    {
        if (m_HostId == -1)
            return;

        var networkEvent = NetworkEventType.Nothing;
        int connectionId;
        int channelId;
        int receivedSize;
        byte error;

        // Get events from the relay connection
        networkEvent =
Unity의 고급 레벨 API를 사용한 통합
일반적인 오류