之前我们讨论过“如何把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/

Steamworks and Unity – P2P多人游戏的更多相关文章

  1. GJM : Unity3D - NetWork - Hight Level API ( HLAPI) [转载]

    介绍在本系列教程中,我们将使用的网络高级API(HLAPI)来构建一个小型的多人网络案例.即使我们的例子很简单,但也会涵盖以下关键概念,这应该可以帮助大家使用HLAPI构建大型游戏项目. 在第一部分, ...

  2. 基于 WebRTC 创建一款多人联机游戏

    本项目的目标旨在尽可能少用服务器资源的前提下研发一款在线多人游戏,同时期望在一个用户的浏览器上运行游戏,同时让另一个玩家来连接.此外还希望程序尽可能简单以便于在博客中分析. 运用的技术 在我刚接触 P ...

  3. Unity接入Steamworks

    一.将scrpts/Steamworks.net/SteamManager组件添加到游戏物体上 二.修改SteamManager的代码为游戏的id如图所示 三.Unity,打开项目根目录,修改stea ...

  4. 关于Unity的网络框架

    注:Unity 5.1里引入了新的网络框架,未来目标应该是WOW那样的,现在还只是个P2P的架子. 网络的框架,无非是如何管理网络数据的收发,通信双方如何约定协议.之前做的框架与GameObject无 ...

  5. Unity Networking API文档翻译(二):The High Level API

    高级API (HLAPI) 是用来提供给Unity 创建多人在线游戏的组件.它是在底层传输层的基础上构建的, 对多人在线游戏提供了很多通用的功能.当传输层支持各种网络拓扑结构的时候,HLAPI是一个功 ...

  6. Unity Networking API文档翻译(一):Networking概述

    写在翻译前的话:      我使用过Photon,研究过Ulink这些Unity提供的多人在线游戏服务器组件,这些商业组件虽然很好很强大.但是对于一个独立开发者来说,4000多软妹币还是点多.总想找一 ...

  7. unity的坑

    http://dearymz.blog.163.com/blog/static/20565742013341916919/ 编辑器: Hierarchy窗口中是场景中的Game Object列表 Pr ...

  8. Unity多玩家网络游戏开发教程1章Unity带有网络功能

    Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件.专门提供了对网络功能的支持. 可是.大部分开发人员第一次接触到的还是Unity自带的网络功能.也就是大家常 ...

  9. 使用Multiplayer Networking做一个简单的多人游戏例子-3/3(Unity3D开发之二十七)

    使用Multiplayer Networking做一个简单的多人游戏例子-1/3 使用Multiplayer Networking做一个简单的多人游戏例子-2/3 使用Multiplayer Netw ...

随机推荐

  1. C#字符串string的常用使用方法(转载)

    1--->字符串的声明: 1.string s=new string(char[] arr)     //根据一个字符数组声明字符串,即将字符字组转化为字符串. 2.string s=new s ...

  2. java的多线程安全,ReentrantLock与synchronized锁

    前言 多线程总的来说是一个很大的模块,所以虽然之前就想写但一直感觉有地方没有理解透,在经过了一段时间学习后,终于有点感觉了,在此写下随笔. 多线程安全问题##: 首先和大家讨论一下多线程为什么会不安全 ...

  3. 多态的作用-游戏编程展示------新标准c++程序设计

    游戏软件的开发最能体现面向对象设计方法的优势.游戏中的人物.道具.建筑物.场景等都是很直观的对象,游戏运行的过程就是这些对象相互作用的过程.每个对象都有自己的属性和方法,不同对象也可能有共同的属性和方 ...

  4. c++缓冲区------c++ Primer Plus

    通常,通过使用缓冲区可以更高效地处理输入和输出.缓冲区是用作中介的内存块,它是将信息从设备传输到程序或从程序传输给设备的临时存储工具.通常,像硬盘驱动器这样的设备以512字节(或更多)的块为单位来传输 ...

  5. React基础篇 (1)-- render&components

    render 基础用法 //1.创建虚拟DOM元素对象 var vDom=<h1>hello wold!</h1> //2.渲染 ReactDOM.render(vDom,do ...

  6. Mongoid Relationships

    1:1 embedded relationship: M:1 linked relationship(one_direction): child uses belongs_to parent uses ...

  7. [SinGuLaRiTy] 2017 百度之星程序设计大赛 初赛A

    [SinGuLaRiTy-1036] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 小C的倍数问题 Time Limit: 2000/100 ...

  8. Postman接口测试之POST、GET请求方法

    一.基础知识 1.HTTP的五种请求方法:GET, POST ,HEAD,OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法. GET请求:请求指定的页面信息,并返回实体 ...

  9. Java的引用和C++的指针de区别

    Java的引用和C++的指针都是指向一块内存地址的,通过引用或指针来完成对内存数据的操作,就好像风筝的线轴一样,通过线轴总是能够找到风筝,但是它们在实现,原理作用等方面却有区别. (1)类型:引用其值 ...

  10. VS2013过期激活

    然后点击"更改我的产品许可证",输入密钥  : BWG7X-J98B3-W34RT-33B3R-JVYW9 即可注册成功...