• Steamworks and Unity – P2P多人游戏


    之前我们讨论过“如何把Steamworks.Net和Unity整合起来”,这是一个很好的开始,现在我们研究深一点,谈一谈Steam中的多人游戏。这不是教程,但是可以指导你在你的游戏中如何使用Steamworks。我们将使用Steamworks .Net的库, steam_api.dll。
     
    注意,你的游戏运行,需要有一个Steam的App Id。你可以在这里申请一个( greenlit),或者由Valve公司直接通过的游戏也有一个Id。这是一个指南,如果你只是想知道Steam是否是一个方便的平台,读下去……

     
    P2P 多人游戏
     
    Steamworks最伟大的特性就是它的匹配机制和P2P网络通信,你不用担心服务器的设置,所有的事情都已经准备就绪。
     
    你可能不熟悉用P2P的连接来建一个多人游戏,现在流行的方法是为客户端和服务器商搭建独立的实体。这种情况下,客户端是游戏本身,服务端是一个包括了服务端逻辑,连接了所有的玩家,保护玩家数据正常不受欺骗的应用程序。客户端、服务端这种模式可能对大型游戏更好,对于一些小的,非竞技类游戏,考虑放弃服务器部分,两个客户端直接对话可能会更好一些。
     
    真的很简单吧?
     
    Steamworks尽可能的让它简单。你不需对链接担心,你只需要一个SteamID(SteamId是用户唯一的标识,它是封装在CSteamID对象中的一个很大的数,你可以用得到跟你互动的用户的CSteamID,例如过通大厅(lobby)得到)。当你有了SteamID之后,你需要执行下面这个方面:
     
    [C#] 纯文本查看 复制代码
     
    1
    // class SteamNetworking
    public static bool SendP2PPacket(CSteamID steamIDRemote, byte[] pubData, uint cubData, EP2PSend eP2PSendType, int nChannel = 0)
    pubData是我们想要发送的数据,cubData是发送数据的字节大小,eP2PSendType是传送的方式,nChannal默认值为空,现在还没有用,不用讨论。
     
    这里是如何发送“Hello!"字串的例子:
     
    [C#] 纯文本查看 复制代码
     
    1
    2
    3
    4
    5
    6
    7
    CSteamID receiver = ...;
    string hello = "Hello!";
     
    // allocate new bytes array and copy string characters as bytes
    byte[] bytes = new byte[hello.Length * sizeof(char)];
    System.Buffer.BlockCopy(hello.ToCharArray(), 0, bytes, 0, bytes.Length);
     
    SteamNetworking.SendP2PPacket(receiver, bytes, (uint) bytes.Length, EP2PSend.k_EP2PSendReliable);


    这里有四种送传的方式:
     
    • k_EP2PSendUnreliable – 小包,可以丢失,不需要依次发送,但要快
    • k_EP2PSendUnreliableNoDelay –     跟上面一样,但是不做链接检查,因为这样,它可能被丢失,但是这种方式是最快的传送方式。
    • k_EP2PSendReliable – 可靠的信息,大包,依次收发。
    • k_EP2PSendReliableWithBuffering –     跟上面一样,但是在发送前会缓冲数据,如果你发送大量的小包,它不会那么及时。(可能会延迟200ms)


     
    另一边做些什么呢?

    如果一个人发送了数据,另一个会以某种方式收到数据。当然,他们都有保密的安全措施。你不会发送数据到你范围之外的其他Steamworks的客户端上。一个Client能接收你的数据之前,他已经和你接受了你的请求,建立起一个P2P会话。

     

    P2P会话请求发生在你第一次向SteamWork客户端发送数据时。当你还有发送任何数据时,这个过程会自动重复(通常是几分钟一次),你应该只接受你希望的连接,例如,你所在大厅(lobby)的其他玩家。

     

    如何接受一个会话请求?非常简单!你可以像下面这样写代码:

    [C#] 纯文本查看 复制代码
     
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // create a callback field. Having a field will make sure that the callback
    // handle won't be eaten by garbage collector.
    private Callback<P2PSessionRequest_t> _p2PSessionRequestCallback;
     
    void Start()
    {
        // setup the callback method
        _p2PSessionRequestCallback = Callback<P2PSessionRequest_t>.Create(OnP2PSessionRequest);
    }
     
    void OnP2PSessionRequest(P2PSessionRequest_t request)
    {
        CSteamID clientId = request.m_steamIDRemote;
        if (ExpectingClient(clientId))
        {
            SteamNetworking.AcceptP2PSessionWithUser(clientId);
        } else {
            Debug.LogWarning("Unexpected session request from " + clientId);
        }
    }



    这样一个P2P会话就会被接受,你就可以开始……
     
    读消息
     

    所有消息都存在Steamwork消息对队列中。你准备取它时就可以读它。一般在Update()函数中要处理这些,你的应用可以尽快的检查到是否有新消息。

     
    [C#] 纯文本查看 复制代码
     
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    void Update()
    {
        uint size;
     
        // repeat while there's a P2P message available
        // will write its size to size variable
        while (SteamNetworking.IsP2PPacketAvailable(out size))
        {
            // allocate buffer and needed variables
            var buffer = new byte[size];
            uint bytesRead;
            CSteamID remoteId;
     
            // read the message into the buffer
            if (SteamNetworking.ReadP2PPacket(buffer, size, out bytesRead, out remoteId))
            {
                // convert to string
                char[] chars = new char[bytesRead / sizeof(char)];
                Buffer.BlockCopy(buffer, 0, chars, 0, length);
     
                string message = new string(chars, 0, chars.Length);
                Debug.Log("Received a message: " + message);
            }
        }
    }

     
    就是这些!

     
    总结

    这个指南没有覆盖清理部分(这不是必须的,因为没有用到的会话会被自动清理)和异常处理。你可以在官方文档读到它们 official Steamworks documentation,。记住你需要成为Steam的伙伴才可能获得,如果你还不是,我希望你读完本文之后,可以考虑成为其中一员。

     

    原文链接:http://blog.theknightsofunity.com/steamworks-and-unity-p2p-multiplayer/

  • 相关阅读:
    网址
    asp.net 各种路径查找
    jquery.nicescroll.js 滚动条插件 API
    课程表上一周下一周
    上一周下一周
    使用NPOI导入导出标准Excel
    FTP文件操作 上传文、 下载文件、删除文件 、创建目录
    asp.net断点续传
    11.06第九次作业
    11.20dezuoye
  • 原文地址:https://www.cnblogs.com/sanyejun/p/8481027.html
Copyright © 2020-2023  润新知