Unity客户端-服务器基础问题

Unity client-server basic questions

我一直在尝试做简单的网络,我可以在其中从一台设备向另一台设备发送消息。我的第一个想法是 'Would I have to pay to use unity multiplayer functionality?' 所以我发现了这个 which seemed clear and directly explained how I would need to do networking in order to maintain zero costs on my behalf. After further searching I discovered this 一点统一文档,它似乎解释了如何以与上一篇文章中描述的相同的方式简单地进行联网,并避开了简单的低级别 API 我想要的消息发送。 [重要说明:我使用 C# 工作]

但我似乎在这个发现之旅中停了下来,因为我没有找到更多的文章或视频来指导我并回答我仍然有关于它如何工作的问题。

所以今天我要问:

A - 你知道任何其他文章或视频可以指导我完成这个吗?

B - 我是不是完全走错了方向?

C - 你能回答我下面的任何关键问题吗?

  1. 创建服务器时,即下面,我应该监听哪个端口,我是否应该担心 'port forwarding' 这是我经常看到的一个短语。

    NetworkServer.Listen(4444);

  2. 创建客户端时,即下面,我应该使用什么 i.p 地址?我认为这是客户端设备的设备,但我怎么知道它是什么?

    myClient.Connect("127.0.0.1", 4444);

  3. 我如何让 2 个设备连接,我的想法是让任何设备默认成为客户端,然后以某种方式 'check for servers' 如果不是,它将创建自己的本地服务器client 供客户端连接,这样就不会有多余的服务器... ?

非常感谢您阅读我的问题,我希望它看起来很清楚,请检查链接,以便您理解。非常感谢任何答案,以便我可以继续我的理解之旅。

首先,不,您无需付费即可使用 Unity 在您的游戏中获得多人游戏功能(至少在一定程度上是这样)。如果您需要的话,最终您显然需要购买或租用服务器来托管游戏的服务器部分。

自从我上次制作多人游戏以来,Unity Networking API 已经有了很大的改进,文档也是如此。

回答您的"key questions":

  1. 您不必担心端口转发。 Unity 的网络 API 无需您的玩家转发端口或任何类似的东西就可以工作。
  2. 这也不是您应该担心的事情。 Unity 会解决这个问题,只需通读文档,您就会明白。
  3. 再次阅读我提供的文档链接,它应该会变得清晰。在你的情况下,因为你想避免给自己带来额外费用,你可能会选择 1 名玩家成为 "Server" 同时也是客户。我可以在这里深入探讨,但教程会提供比我能给出的更好的解释。

祝你的项目顺利,我希望它对你有用。

  • AE
  1. what port should i listen on and should I worry about 'port forwarding' which is a phrase I see often chucked about.

这取决于你。您可以使用任何您想要的端口。正确的做法是 select 为您的游戏选择 10 端口,然后选择 1 端口作为默认端口。例如,让我们选择端口 1000010010。让我们将端口 10000 设为您的默认游戏端口。

如果您尝试使用 NetworkServer.Listen(10000) 连接到默认 (10000) 但有其他软件正在使用该端口或该端口不可使用,NetworkServer.Listen 将return false 并抛出以下异常:

Cannot open socket on ip {*} and port {10000}; check please your network, most probably port has been already occupied

发生这种情况时,您可以尝试下一个端口、另一个下一个端口和另一个端口,直到达到最大游戏端口 10010

此外,在您的游戏说明中,您可以指示玩家在连接到其他玩家时遇到问题时打开端口 1000010010

实现(阅读代码中的注释):

int minPort = 10000;
int maxPort = 10010;
int defaultPort = 10000;

//Creates a server then returns the port the server is created with. Returns -1 if server is not created
int createServer()
{
    int serverPort = -1;
    //Connect to default port
    bool serverCreated = NetworkServer.Listen(defaultPort);
    if (serverCreated)
    {
        serverPort = defaultPort;
        Debug.Log("Server Created with deafault port");
    }
    else
    {
        Debug.Log("Failed to create with the default port");
        //Try to create server with other port from min to max except the default port which we trid already
        for (int tempPort = minPort; tempPort <= maxPort; tempPort++)
        {
            //Skip the default port since we have already tried it
            if (tempPort != defaultPort)
            {
                //Exit loop if successfully create a server
                if (NetworkServer.Listen(tempPort))
                {
                    serverPort = tempPort;
                    break;
                }

                //If this is the max port and server is not still created, show, failed to create server error
                if (tempPort == maxPort)
                {
                    Debug.LogError("Failed to create server");
                }
            }
        }
    }
    return serverPort;
}

用法:

void Start()
{
    int serverPort = createServer();
    if (serverPort != -1)
    {
        Debug.Log("Server created on port : " + serverPort);
    }
    else
    {
        Debug.Log("Failed to create Server");
    }
}
  1. When creating a client, i.e below, what i.p address should i use? I presume it is that of the client's device but how do i know what it is?

过去,您必须使用 UDP 将 IP 广播到网络。简而言之,您从计算机获取 IP 地址,然后将其广播到 255.255.255.255.

您还可以向修改后的 IP 地址广播。假设您的 ip 是 192.168.1.13,您应该删除 13(最后一个八位字节)并将其替换为 255,然后将您的 ip 广播到 192.168.1.255。我对此进行了更多解释

了解什么是广播很重要,但 Unity 通过创建广播 API NetworkDiscovery 使其变得更简单。

要知道要连接到哪个 IP 地址,只需在服务器端的 Start() 函数中调用 NetworkDiscovery.StartAsServer()

在您的客户端,调用 NetworkDiscovery.StartAsClient() 然后实现 OnReceivedBroadcast(string fromAddress, string data); 函数。当找到服务器时 OnReceivedBroadcast(string fromAddress, string data);将被调用,然后您可以使用 returned fromAddress 值连接到您的服务器。

这也应该回答您的 #3 问题。另外,很高兴您发现我的 回答很有用。