UE4中的网络模式
Actor中的GetNetMode
Actor 中有个函数 GetNetMode 可以用来判断当前 Actor 所处的网络模式,如下
-
NM_Client: 客户端,联机模式中的客户端 -
NM_Standalone: 运行在服务器模式下,同时包含客户端的功能,也就是平常意义上的单机模式,比如在编辑器中把number of Players设置为1,并且不勾选Run Dedicated Server时,就会运行在这个模式下
-
NM_DedicatedServer: 运行在服务器模式下,只包含服务器功能,这个是纯服务器模式,不会有客户端相关的功能运行,比如渲染相关的模块 -
NM_ListenServer: 运行在服务器模式下,同时包含客户端的功能,同时也作为主机让其他客户端连接进行联网游戏,比如很多游戏中的局域网模式。在编辑器中把number of Players设置为大于1,并且不勾选Run Dedicated Server时,主机就会运行在这个模式下
以上三个模式都可以认为是服务器,区别就是带不带本地玩家,能不能让其他机器连接
| 模式 | 是否带本地玩家 | 是否能作为主机 |
|---|---|---|
NM_Standalone |
是 | 否 |
NM_DedicatedServer |
否 | 是 |
NM_ListenServer |
是 | 是 |
编译时确定的网络模式
虚幻中有一堆宏来控制编译,和网络模式相关有如下几个
UE_SERVER: 开了这个宏的肯定是服务器了,编译时就会把客户端相关的模块给剔除掉,比如渲染相关的WITH_SERVER_CODE: 这个宏来控制网络逻辑代码的开关,如果是!WITH_SERVER_CODE,那就是纯客户端了,在PlatformProperties.h中,FWindowsPlatformProperties/FMacPlatformProperties/FLinuxPlatformProperties,这三个模板类的IS_CLIENT_ONLY参数传的就是!WITH_SERVER_CODE
FPlatformProperties 中封装了几个函数来判断编译是以什么模式来编译的
-
IsServerOnly: 如果是true则表示编译的时候是以DedicatedServer的模式来编译代码,会剔除客户端相关的模块代码,比如渲染模块,也不包含Editor相关的代码 -
IsGameOnly: 如果是true则表示编译时剔除了Editor相关的代码 -
IsClientOnly: 如果是true则表示编译时剔除了服务器和Editor相关的代码,这里需要注意的是,在以xxx Client模式来出包时,如果出的是Windows/Mac/Linux,则这个函数返回的是true,如果出的是移动端的包,则返回的是false,因为FIOSPlatformProperties/FAndroidPlatformProperties,没有覆盖父类中的默认IsClientOnly实现,父类的默认实现返回的的false,不明白这里为啥行为不一致
IsRunningDedicatedServer/IsRunningGame/IsRunningClientOnly
这几个函数和上面的三个函数功能类似,在非Editor模式下的返回值和上面三个函数一致,区别在于当运行Editor时,可以通过命令行来切换运行模式,具体如下
- 命令行中包含
SERVER或者RUN=SERVER时,以DedicatedServer模式模拟运行 - 命令行中包含
GAME时,以无Editor模式模拟运行 - 命令行中包含
GAME和ClientOnly时,以纯客户端模式模拟运行
编译配置和GetNetMode的关系
| 编译配置 | 联机模式(主机)GetNetMode返回值 | 联机模式(客户端)GetNetMode返回值 | 单机模式GetNetMode返回值 |
|---|---|---|---|
| xxx Client | 无此模式 | NM_Client |
NM_Standalone |
| xxx Server | NM_DedicatedServer |
无此模式 | 无此模式 |
| Debug/DebugGame/Development/Shipping | NM_ListenServer |
NM_Client |
NM_Standalone |
总结
-
在
Actor中有些游戏逻辑函数是服务器客户端都能调用的,如果要判断是谁触发的调用,最好的方式是通过属性Role来判断,一般Role == ROLE_Authority的时候就可以认为是服务器,不过要注意的是,如果客户端自己Spawn了一个Actor,那么这个Actor的Role也是ROLE_Authority。如果只是要判断当前运行的网络模式环境,可以通过GetNetMode来判断。 -
在其他地方判断运行环境,最好的方式是使用
IsRunningDedicatedServer/IsRunningClientOnly,这样保证PIE测试时也没问题
