PixelStreaming是UE_4.21开始支持的一项技术,简单来说就是能够将游戏跑在服务器上,你可以通过浏览器来玩,玩家端不需要额外操作,只需要一个浏览器,所有的逻辑处理和渲染都在“云”端执行。它不仅仅只是一个插件(虽然有PixelStreamingPlugin这个插件,但它只是PixelStreaming实现中的一环),其实现具有一套独立与UE游戏的设计和组织方式。
本篇文章主要介绍PixelStreaming中的基本概念和使用PixelStreaming的Demo的实际体验。
来看一下UE自己的介绍:
Run your Unreal Engine application on a server in the cloud, and stream its rendered frames and audio to browsers and mobile devices over WebRTC.
PixelStreaming的数据传输使用的是WebRTC,P2P的连接延迟更低。
注意:本文所描述内容的测试引擎为UE_4.22.3,目前PixelStreaming只能运行在Windows平台(依赖于模块
D3DX11
和NvVideoEncoder
库)。
UE提供的PixelStreaming展示案例的代码分成了几个部分:
- PixelStreamingPlugin:提供渲染帧与音频数据的捕获与编码,并创建一个链接将音频和渲染帧的数据传递给WebRTC服务器,使用的是UE的插件方式编写和使用。
- WebRTCProxy:应用/游戏与WebServer交流的中间层,作用是将游戏内编码好的渲染帧数据(.h264)与音频数据传递给WebServer,并从WebServer上接收到的用户输入再传递给应用/游戏,从而可以从浏览器上控制游戏。使用UE的Program方式编写。
- WebServer:PixelStreaming设计的组织方式中,WebServer是由两个模块组成:SignalingWebServer与Matchmaker,使用的是nodejs编写。
- SignallingWebServer:启动一个HTTP服务,从WebRTC接收渲染帧和音频数据传递给浏览器客户端,并接收远程用户的输入(键盘、鼠标等)再传递给WebRTC。
- MatchMakerServer:如果只是启动一个游戏实例和单个的SignallingWebServer,那么使用浏览器访问的玩家操作的都是同一个游戏实例,他们的键盘和鼠标操作都会相互干扰。解决这个的问题的办法使用MatchMakerServer,但是这种方式也是需要启动多套游戏实例/WebRTCProxy以及SignallingWebServer,供外部用户每个人访问不同的游戏实例,使每个浏览器访问的客户端具有不同的连接。
用户访问单个实例的流程如下图:
后续我会逐个分析一下它们各自的代码实现(上周末的简单分析了一下PixelStreamingPlugin的实现),这篇文章的目的是介绍基本概念和简单的PixelStreamingDemo上手。
本篇文章的参考资料主要是UE文档库中对于PixelStreaming的介绍,以及我读代码了解到的实现方式,目前官方文档页面的描述不是特别详细,有些细节和可以用的参数命令没有提及,还是看代码靠谱。
PixelStreamingDemo
基本概念介绍完毕,下面进入实际的上手环节。
Launch Game
首先创建一个C++项目,我选择了一个第三人称模板:
创建完成之后,打开Edit
-Plugins
搜索启用PixelStreaming
:
然后重启编辑器。
与UE的官网介绍(Getting Started with Pixel Streaming)的需要打包不同,只要使用Standalone模式启动项目就可以加载PixelStreamingPlugin
,这样可以省去每次都要打包的麻烦。
为了方便添加启动参数,可以使用我之前写的一个工具:UE4 Launcher
并为其添加启动参数-game
/-log
/-AudioMixer
(PixelStreamingPlugin需要这个参数):
注:PixelStreamingPlugin支持启动时指定要连接的WebRTCProxy的地址与端口,可以在上面的启动参数列表中添加。
-PixelStreamingIP=<value>
:指定WebRTCProxy服务器的地址,默认为0.0.0.0
.-PixelStreamingPort=<value>
:指定WebRTCProxy服务器的端口,默认为8124
.
然后点击Launch Configuration
即可以Standalone模式启动项目。
启动之后可以从Log窗口中看到PixelStreaming的Log输出:
WebRTCProxy
经过上面的操作游戏启动完成之后,可以启动WebRTC了,打开引擎目录:
1 | Engine\Source\Programs\PixelStreaming\WebRTCProxy\bin |
可以看到目录下有五个文件:
1 | 2019/07/29 01:21 110 Start_AWS_WebRTCProxy.bat |
需要做的只有双击Start_WebRTCProxy.bat
启动(它里面也仅仅只是启动了WebRTCProxy.exe).
启动之后可以看到连接信息:
此时在打开游戏项目的Log窗口可以看到如下内容:
1 | [2019.07.30-08.18.49:324][758]PixelStreamingNet: Accepted connection from WebRTC Proxy: 127.0.0.1:2703 |
表明PixelStreamingPlugin与WebRTCProxy已经连接成功了。
WebRTCProxy也可以指定游戏内PixelStreamingPlugin设定的端口,以及SignallingWebServer的地址/端口,可以通过-help
参数来查看WebRTCProxy支持的参数(这部分的实现代码在Engine/Source/Programs/PixelStreaming/WebRTCProxy/src/WebRTCProxy.cpp中):
1 | E:\UnrealEngine\Epic\UE_4.22\Engine\Source\Programs\PixelStreaming\WebRTCProxy\bin>WebRTCProxy.exe -help |
其中:
-Cirrus=<IP:Port>
用来指定与SignallingWebServer通信的端口(默认为127.0.0.1:8888
).-UEPort=<Port>
:用来指定与该WebRTCProxy关联的UE应用的端口(PixelStreamingPlugin中的连接端口,默认为127.0.0.1:8124
)
SignallingWebServer
当游戏与WebRTCProxy都启动完毕之后,需要开始启动真正供浏览器可访问的HTTP服务器了。
首先需要安装node,下载安装之后将其添加到系统的PATH路径,通过命令node -v
与npm -v
测试是否安装成功:
1 | C:\Users\imzlp\Desktop>node -v |
如上图则没有问题,可以启动SignallingWebServer了,打开引擎目录:
1 | Engine\Source\Programs\PixelStreaming\WebServers\SignallingWebServer |
里面有一堆的文件,需要启动的是run.bat
或者runNoSetup.bat
(他们两个唯一的区别为是否执行npm install
),如果你是第一次打开,则以管理员权限启动run.bat
,后续直接启动runNoSetup.bat即可
。
经过一堆的npm包的下载与安装之后,启动成功:
此时打开WebRTCProxy的窗口界面,可以看到以下内容:
此时所有需要启动的服务都已启动完毕。
注:SignallingWebServer默认连接
127.0.0.1:8888
的WebRTCProxy,并开启一个80端口的HTTP服务。
- 使用
--proxyPort <Port>
可以修改监听的WebRTCProxy端口,或者写在SignallingWebSerber/config.json
配置下。- 使用
--httpPort <Port>
可以修改启动的HTTP服务器的端口。
打开浏览器输入http://127.0.0.1(使用的是默认端口80,不然需要指定端口号https://127.0.0.1:xxxx)就可以看到以下界面:
鼠标点击即可进入游戏画面:
其他的移动设备如果在同一个网段,也是可以直接连接的:
我也录了一个简单的视频(在ipad上操作):
MatchMakerServer
在文章的最开始,我简单说明了一下MatchMakerServer的用途,下面简单说一下如何做。
先来看UE对MatchMakerServer的职责图:
用法为:在启动单个的SignallingWebServer时,指定参数启用Matchmaker
:
1 | runNoSetup.bat --UseMatchmaker --matchmakeAddress 127.0.0.1 --matchmakerPort 9999 |
然后启动MatchmakerServer,找到以下路径:
1 | Engine\Source\Programs\PixelStreaming\WebServers\Matchmaker |
直接启动run.bat
的默认httpPort
为90,matchmakerPort
为9999,即上面运行SignallingWebServer时指定的--matchmakerPort 9999
,可以自己使用参数替换。
1 | run.bat --httpPort 88 --matchmakerPort 9988 |
下面使用的是默认的httpPort
/matchmakePort
端口
然后访问http:127.0.0.1:90,可以看到与单独启动的SignallingWebServer一样,但是不允许其他的客户端再加入到当前的会话中来,会提示WARNING: No empty Cirrus servers are available
。
除非同时运行多套游戏/WebRTCProxy/SignallingWebServer,使每个玩家独占一套不相互干扰,这也是MatchmakerServer的作用所在。
结语
Pixel Streaming这种“云”游戏的思路很好,但是目前的硬件环境和带宽瓶颈还是很大的问题,在我测试体验的过程中,局域网连接比较流畅,在设定最高60fps的情况下可以跑到满帧,但是也是会出现偶尔掉帧的情况。
Google也推出了云游戏平台Stadia,但是离真的可以落地还很远,但是目前做一些行业应用还是可以的(比如雪佛兰的汽车展示2020 CORVETTE STINGRAY)。