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
测试时也没问题