前言

  根据UE4官方文档的介绍,UE4引擎在架构时就已经考虑到了多人游戏的情景,多人游戏基于客户端-服务器模式(CS模式)。也就是说,会有一个服务器担当游戏状态的主控者,而连接的客户端将保持近似的副本。服务器是UE4多人游戏的一个重要部分,其作用是:做出所有重要决定,包含所有的主控状态、处理客户端连接、转移到新的地图以及处理比赛开始/结束时的总体游戏流程。

  服务器的功能开发在UE4中也非常简单,UE4本身是支持客户端/服务器逻辑混合开发的,在蓝图中创建好自定义事件(Custom Event)之后,只需要选择该事件在服务器上运行(Run on Server)即可。而在C++中,也只需要用宏UFunction(Server)来修饰某个函数,然后就可以在客户端调用服务器RPC。本文在此不再具体赘述服务器游戏功能的实现,而是着重介绍如何构建出独立的UE4服务器应用。

服务器构建

  在UE4编辑器中,我们只需要在播放(Play)选项中勾选运行独立服务器(Run Dedicated Server)即可在编辑器中运行独立服务器,并且客户端会自动连接到该服务器。那么如何构建出能独立运行的服务器呢?官网给出了一篇指南,于是我根据这篇指南和我自己的理解开始了UE4服务器的构建。

编译虚幻引擎源码

  在这第一步我就产生了疑问,我们最初从官网下载UE4启动器后,安装UE4引擎时,不就已经下载了虚幻引擎源码了吗,还有必要重新下载吗?

  于是我就尝试跳过这一步,直接从添加构建服务器目标开始操作,当选择构建目标为"Development Server"后,得到了如下的报错:

UnrealBuildTool : error : Couldn't find target rules file for target 'UE4Server' in rules assembly 'UE4Rules, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Location: C:\Program Files\Epic Games\UE_4.22\Engine\Intermediate\Build\BuildRules\UE4Rules.dll
Target rules found:

  该问题我在Reddit(国外知名论坛)上找到了详细的阐述,原因就是因为没有按照指南的步骤下载与编译UE4源码。至于为何启动器中下载的UE4引擎源码会出现找不到构建目标“UE4Server”的问题,我推测是因为其源码(构建)不完整,精简了编辑器以外的其他内容(例如独立服务器模块等等),所以,还是老老实实下载源码吧。

下载UE4源码

  UE4源码存放在Github仓库,并且是私有仓库(private reposity)。如果你想获得访问权限,需要加入Epic Games开发组。在Epic官网登陆帐号后,关联Github帐号,就会收到Epic Games开发组的邀请,接受后即可加入,官网做了详细的操作教程。

  我下载的版本是4.22.3,大小是333M,如果你访问Github速度过慢,可以从我的百度网盘中下载(提取码:fv4e)。

安装源码

  解压上一步下载的源码压缩包后,双击Setup.bat文件即可。

  可以看到,该一步是在检查和更新UE4引擎的依赖组件,需要更新9122M的文件(约9G),国内访问速度特别慢,我家100M电信宽带,下载速度只有0.1M/S(100KB/S),连上香港的VPN也是差不多的速度(因为VPN限速1M),按照这个下载速度,下载完大约需要25个小时

  25个小时有点太长了,查看了一下Setup.bat这个文件,它调用了“.\Engine\Binaries\DotNET\GitDependencies.exe”来执行下载,查看该进程连接的远程地址为“13.225.102.98:80”,这个ip地址在美国,所以访问缓慢。我找了一下源码目录,希望可以找到配置类似下载镜像的地方,但最终并没有找到。(绝望~)

  难道真的要为此默默等待25小时吗?好在生活中处处有惊喜,第二天我试了一下在公司网络进行下载,速度意外地飚到了1.5M/S,只需要等待大约1个半小时,非常开心。下载完毕后,该窗口会自动消失,继续进行下一步即可。如果你也有下载依赖缓慢的问题,可以从我的百度网盘中下载(提取码:qa8a)。

生成Visual Studio项目文件

  同样在解压后的路径,双击GenerateProjectFiles.bat,会得到如下的报错:

  根据提示来看,是因为需要安装.net框架的SDK。打开微软.NET官网,下载.NET Framework Dev Pack(注意不是Runtime)。

  (Warning!)此处有巨坑。根据上面的提示,是需要安装4.6.2版本的.NET Framework Dev Pack,如果你跟我一样直接下载了目前最新的版本(4.8),同样会有该错误提示,因为这个版本要求已经写在了如下的文件中:

Engine\Source\Programs\UnrealBuildTool\UnrealBuildTool.csproj
Engine\Source\Programs\DotNETCommon\DotNETUtilities\DotNETUtilities.csproj

  “机智”的我立刻找到了文件中的TargetFrameworkVersion字段,将默认的v4.6.2修改成了我安装的版本v4.8,再次运行GenerateProjectFiles.bat后,果然,没有报错,并且成功生成了UE4.sln。其实,如上的步骤并不是指跳过了这个巨坑,因为,这只是噩梦的开始...

  继续进行下面的编译源码步骤后(耗时约8小时),会得到如下的报错:

error MSB3075: The command "..\..\Build\BatchFiles\Build.bat exited with code 5.
Please verify that you have sufficient rights to run this command.

  根据报错提示,是"....\Build\BatchFiles\Build.bat"异常退出,因为没有权限。我推测可能是由于文件占用导致的,先是重启了VS再编译,没有效果。然后又重启了电脑,仍然没有效果。然后又尝试了“使用管理员权限”重新编译,还是没有变化。百度和Google上的解决方法也是五花八门,各种情况都有,无法解决。

  最后正在我绝望的时候,突然想到了.NET版本的问题,卸载.NET Dev Pack 4.8然后重新安装.NET Dev Pack 4.6.2之后。终于,报错消失了,所以,这里只能使用.NET Dev Pack 4.6.2。

  这个大坑主要是因为.NET Dev Pack版本安装错误后,没有明确的提示,不太容易联想到是.NET Dev Pack版本的问题,而且,编译一次UE4源码真的太太太太太耗时间了。

编译UE4源码

  双击UE4.sln在Visual Studio中打开UE4源码,在左侧解决方案浏览器(Solution Explorer)中,在“UE4”项目点击右键,然后点击Build。考验电脑性能的时候到了,我在公司的i3处理器的电脑上编译了大概8个小时,并且在编译期间,CPU占用率一直100%,几乎干不了其他事,所以建议在下班的时候进行,第二天早上一上班就可以看到,编译已经完成。

为项目添加构建服务器目标

  由于官网的指南是针对引擎版本为“4.14, 4.15, 4.16, 4.17, 4.18”编写的,而我使用的UE4引擎版本为4.22.3,因此使用的是指南中针对4.18版本的内容,经过测试,是可以使用的。

  进入项目的"~/Source"路径,新建一个文件命名为“项目名Server.Target.cs”,将项目名替换为实际项目名,例如我的项目名为“Shooting_Game”,则文件名命名为“Shooting_GameServer.Target.cs”。(如果你的项目没有Source路径,则说明是纯蓝图的UE4项目,则在编辑器中添加任意一个C++类即可。)

  编辑新建的文件,加入如下内容,注意替换项目名。

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;
using System.Collections.Generic; [SupportedPlatforms(UnrealPlatformClass.Server)]
public class Shooting_GameServerTarget : TargetRules // 修改项目名
{
public Shooting_GameServerTarget(TargetInfo Target) : base(Target) // 修改项目名
{
Type = TargetType.Server;
ExtraModuleNames.Add("Shooting_Game"); // 修改项目名
}
}

切换项目的UE4引擎版本

  右键项目根目录的“项目名.uproject”文件,选择"Switch Unreal Engine version..."

  选择刚刚安装的UE4引擎版本,点击OK即可,切换引擎后,会自动生成项目文件(Project files)。

构建服务器

  在Visual Studio的解决方案配置(Solution Configuration)中选择"Development Server",然后在解决方案浏览器(Solution Explorer)中,在"Shooting_Game"(我的项目名称)点击右键,点击Build。这里只有481个构建步骤,比编译UE4源码要少 一些,大约需要2小时。

  构建完成之后,可以看到输出日志:

[480/481] Shooting_GameServer.exe
Creating library F:\workspace\ue4\Shooting_Game2\Binaries\Win64\Shooting_GameServer.lib and object F:\workspace\ue4\Shooting_Game2\Binaries\Win64\Shooting_GameServer.exp
[481/481] Shooting_GameServer.target

  已经生成了Shooting_GameServer.exe,路径在“~\Binaries\Win64\”,如果我们尝试直接运行(需要添加运行参数-log,否则进程会在后台运行,什么效果也看不到),会看到如下报错:

LogLinker: Warning: Unable to load package(...). Package contains EditorOnly data which is not supported by the current build.

  意思是包含了仅支持编辑器内容的数据,“~\Binaries\Win64\”是编辑器构建文件夹,所以我们还需要进行客户端打包,然后再将服务器程序拷贝过去。

客户端打包

  客户端打包需要在编辑器中进行,所以需要在解决方案配置(Solution Configuration)中选择"Development Editor",启动项目(Startup Projects)中选择“Shooting_Game”,然后点击运行按钮。第一次运行编辑器会编译Shader,所以耗时较久(我大约需要20分钟),并且会长时间卡在45%,等待即可。

创建入口关卡

  在左下方内容浏览器(Content Browser)中选择Content目录,选择存放关卡的文件夹(我的是Levels),右边窗口右键创建关卡(Level),命名为EntryMap。

在入口关卡中连接服务器

  双击选择EntryMap,然后在上方工具栏选择蓝图(BluePrints),打开关卡蓝图(Open Level BluePrint)。引出BeginPlay引脚,选择OpenLevel,在LevelName中填写服务器IP地址,保存编译。

创建过渡关卡

  用同样的方式创建关卡,命名为TransitionMap,无需给该关卡添加内容,保持空白即可。

指定游戏地图

  菜单栏选择编辑(Edit)- 项目设置(Project Settings)- 项目(Project)- 地图和模式(Maps & Modes)- 默认地图(Default Maps),依次将编辑器初始地图(Editor Startup Map)设置为GameMap,游戏默认地图(Game Default Map)设置为EntryMap,过渡地图(Transition Map)设置为TransitionMap,服务器默认地图(Server Default Map)设置为GameMap。

打包地图设置

  菜单栏选择编辑(Edit)- 项目设置(Project Settings)- 项目(Project)- 打包(Packaging)- 打包地图列表(LIst of maps to include in a packaged build),分别添加EntryMap,TransitionMap,GameMap。

开始打包

  菜单栏选择文件(File)- 打包项目(Package Project)- 窗口(Windows)- 64位窗口(Windows(64 bit)),然后选择打包目录,即可开始打包。

UATHelper: Packaging (Windows (64-bit)): BUILD SUCCESSFUL
UATHelper: Packaging (Windows (64-bit)): AutomationTool exiting with ExitCode=0 (Success)

  根据提示,可以看到,打包成功。

运行服务器

  之前已经提到,构建出的服务器目标文件需要在客户端资源目录中运行,因此需要拷贝过去。

拷贝服务器目标文件

  将之前构建出的“~\Binaries\Win64\Shooting_GameServer.exe”拷贝到客户端的打包目录"WindowsNoEditor\Shooting_Game\Binaries\Win64"。

在命令行中运行服务器

  由于服务器没有图形界面(GUI),因此需要在命令行中运行,否则什么输出都看不到。给拷贝过来的Shooting_GameServer.exe创建快捷方式,并在“目标”后加入“ -log”。

  双击运行该快捷方式,可以看到一下日志:

LogInit: WinSock: I am PC-20190329KLKV (192.168.52.160:0)
LogNet: GameNetDriver IpNetDriver_0 IpNetDriver listening on port 7777
LogWorld: Bringing World /Game/Levels/GameMap.GameMap up for play (max tick rate 30) at 2019.10.09-11.20.56
LogWorld: Bringing up level for play took: 0.002008
LogLoad: Took 0.129134 seconds to LoadMap(/Game/Levels/GameMap)
LogLoad: (Engine Initialization) Total time: 1.03 seconds

  可以看到,服务器运行在192.168.52.160,监听端口为7777。打开cmd命令行,输入netstat -an|FIND "7777"

UDP    0.0.0.0:7777           *:*

  由此可见,UE4服务器与客户端连接使用的是UDP协议,默认端口为7777。

  至此,UE4项目的服务器构建完成,可以使用打出的客户端包来进行连接测试。

效果演示

来玩一局CS吗?UE4射击游戏的独立服务器构建的更多相关文章

  1. [UE4]虚幻4链接独立服务器

    如果虚幻4只做客户端的话,应该怎么连接服务器呢? 官方并没有提供蓝图的网络函数,C++里面有. 一.自己实现,提供接口给蓝图使用. 二.第三方插件.插件下载地址:https://github.com/ ...

  2. UE4蓝图与C++交互——射击游戏中多武器系统的实现

    回顾   学习UE4已有近2周的时间,跟着数天学院"UE4游戏开发"课程的学习,已经完成了UE4蓝图方面比较基础性的学习.通过UE4蓝图的开发,我实现了类似CS的单人版射击游戏,效 ...

  3. 简单的射击游戏HTML+JS实现

    一直想自己写一个游戏玩,时间和精力都不太允许,最近几天刚好有空闲时间,就琢磨了这个小游戏. 刚开始想着计算图片重叠事件,然后让炮弹和飞机消失,傻乎乎写了一天,越整越乱.今天一大早晕过来了,改用数组以后 ...

  4. Unity3D--学习太空射击游戏制作(二)

    步骤三:创建主角 游戏的主角是一艘太空飞船,我们将使用一个飞船模型作为游戏的主角,并赋予他一个脚本,控制他的运动,游戏体的组件必须依赖于脚本才能运行. 01:在Project窗口找到Player.fb ...

  5. cocos2d-x学习日志(10) --射击游戏(喵星战争)

    转载请标明:转载自[小枫栏目],博文链接:http://blog.csdn.net/rexuefengye/article/details/10553487 一.纵版射击游戏的特点 纵版射击游戏是一种 ...

  6. Skytte:一款令人印象深刻的 HTML5 射击游戏

    Skytte 是一款浏览器里的 2D 射击游戏.使用 Canvas 元素和大量的 JavaScript 代码实现.Skytte 是用我们的开源和现代的前端技术创造的.经典,快节奏的横向滚动射击游戏,探 ...

  7. 一款简单射击游戏IOS源码

    源码描述: 一款基于cocos2d的简单设计游戏,并且也是一款基于cocos2d的简单射击游戏(含苹果IAD广告), 游戏操作很简单,哪个数字大就点击射击哪个.里面有苹果iad广告,功能简单完整,适合 ...

  8. 《Genesis-3D开源游戏引擎完整实例教程-2D射击游戏篇08:弹幕系统》本系列完结

    8.弹幕系统 弹幕系统概述: 弹幕系统的设计体现了射击游戏的基本要素,玩家要在敌人放出的大量子弹(弹幕)的细小空隙间闪避,能在玩家闪躲弹幕的时候给玩家带来快感,接近满屏的子弹,增加了对玩家的视觉冲击力 ...

  9. 有图有真相,分享一款网页版HTML5飞机射击游戏

    本飞机射击游戏是使用HTML5代码写的,尝试通过统一开发环境(UDE)将游戏托管在MM应用引擎,直接生成了网页版游戏,游戏简单易上手,非常适合用来当做小休闲打发时间. 游戏地址:http://flyg ...

随机推荐

  1. 面试题:Python大小写转换

    小文:今天面试又搞砸了? 小 k:怎么了? 小文:又一个大小写转换的题目感觉答错了. 小 k:说来听听. 小文:将"hello world"转换为首字母大写"Hello ...

  2. CSS 预处理语言之 Scss 篇

    简介 1. Sass 和 Scss Sass 和 Scss 其实是同一种东西,我们平时都称之为 Sass:Scss 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强 ...

  3. 在Linux环境下采用压缩包方式安装JDK 13

    本文地址:https://www.cnblogs.com/oberon-zjt0806/p/11663731.html 可以,转载,出处,格式,懂?? 什么是JDK?? 好吧如果你不知道这个问题的话我 ...

  4. goLang 纳秒转 毫秒 转 英文时间格式

    package main import ( "fmt" "time" ) func main(){ fmt.Println(time.Now().Unix()) ...

  5. Android 总结:ContentProvider 的使用

    一.概述 ContentProvider:为存储和获取数据提供统一的接口,可以在不同的应用程序之间共享数据. Android内置的许多数据都是使用ContentProvider形式,供开发者调用的 ( ...

  6. vue3.0的安装使用

    关于旧版本 Vue CLI 的包名称由 vue-cli 改成了 @vue/cli. 如果你已经全局安装了旧版本的 vue-cli (1.x 或 2.x),你需要先通过 npm uninstall vu ...

  7. 洛谷 P3745 [六省联考2017]期末考试

    题目描述 有 nnn 位同学,每位同学都参加了全部的 mmm 门课程的期末考试,都在焦急的等待成绩的公布. 第 iii 位同学希望在第 tit_iti​ 天或之前得知所有课程的成绩.如果在第 tit_ ...

  8. Cow Acrobats

    Farmer John's N (1 <= N <= 50,000) cows (numbered 1..N) are planning to run away and join the ...

  9. Python_散点图绘制

    为了可视化一些数据分布,需要以散点图的形式呈现 引入绘图工具 import matplotlib.pyplot as plt from matplotlib.font_manager import F ...

  10. 构造函数语义学——Default Constructor篇

    构造函数语义学--Default Constructor 篇 这一章原书主要分析了:编译器关于对象构造过程的干涉,即在对象构造这个过程中,编译器到底在背后做了什么 这一章的重点在于 default c ...