UE5专用服务器(DS)与客户端完整打包部署实战指南

发布时间:2026/7/22 4:03:10

UE5专用服务器(DS)与客户端完整打包部署实战指南 1. 项目概述为什么UE5的DS打包是个技术活如果你正在用UE5开发一个多人游戏并且已经走到了“打包部署”这一步那你大概率已经和蓝图、C、网络同步这些概念搏斗过一番了。但当你兴冲冲地点击“打包项目”准备把劳动成果分发给朋友或部署到服务器上时很可能会遇到一堆新问题为什么打包出来的客户端运行不了服务端程序在哪怎么让它们通过网络互相找到对方这些问题正是“从零构建DS服务端与客户端完整打包”这个主题要解决的核心痛点。DS在这里特指Dedicated Server即专用服务器。它和我们在编辑器里点击“Play”时自动在本地启动的那个“Listen Server”监听服务器有本质区别。专用服务器是一个独立的、没有图形界面、纯粹负责游戏逻辑和网络同步的可执行程序。对于任何严肃的多人游戏项目无论是小型合作还是大型在线游戏最终都需要将游戏逻辑服务端和表现层客户端分开打包、独立部署。这个过程UE5引擎本身提供了支持但默认配置和流程中藏着不少“坑”需要开发者手动趟过去。这个指南的目的就是带你完整地走一遍这个流程。我不会只告诉你“点击这里再点击那里”而是会拆解每一步背后的逻辑为什么需要这个配置这个参数改动会影响什么当打包失败时应该从哪个日志文件开始排查我会基于一个典型的UE5多人游戏项目比如一个简单的第三人称射击或生存建造模板演示如何配置项目设置、编写必要的代码逻辑、处理平台差异并最终生成可以独立运行的客户端.exe和服务端.exe程序包。无论你是独立开发者还是团队中的技术负责人掌握这套流程都能让你在项目交付和测试部署阶段更加从容。2. 核心概念与项目前置配置在动手打包之前我们必须先统一几个关键概念并确保项目的基础配置是正确的。很多打包失败的问题根源都出在项目配置阶段。2.1 理解UE5中的三种网络模式UE5以及之前的UE4主要支持三种网络模式理解它们对打包至关重要单机模式没有网络功能所有逻辑在本地运行。打包最简单但与我们的话题无关。监听服务器这是编辑器内测试最常用的模式。当你作为主机开始游戏时你的机器同时运行着完整的客户端包括渲染、输入、UI和服务端逻辑。其他玩家作为客户端连接到你的机器。这种模式打包出的程序通常是一个“可兼作主机的客户端”但它不适合作为7x24小时运行的稳定服务器。专用服务器一个纯粹的服务端程序没有图形渲染、没有本地玩家输入处理。它只运行游戏规则、同步状态、处理客户端RPC。它更节省资源运行更稳定是生产环境的标准选择。我们的目标就是生成专用服务器程序和纯客户端程序。2.2 关键项目设置检查清单在打包前请务必在项目设置中核对以下关键项。这些设置分散在不同的面板中漏掉任何一个都可能导致打包失败或运行时异常。2.2.1 地图与模式设置进入项目设置 - 地图与模式。默认地图设置你的游戏主菜单或初始连接地图。服务器默认地图这是最关键的一项必须设置一个专门给专用服务器启动后加载的地图。这个地图应该是一个“空”的、只包含必要世界设置和游戏模式的关卡通常不包含任何仅客户端可见的视觉效果或体积。你可以复制你的主游戏地图然后删除所有灯光、特效、仅客户端的Actor得到一个轻量级的服务端版本。例如L_ServerStartup。默认游戏模式确保你设置的游戏模式类如BP_MyGameMode是正确继承自GameMode且网络复制功能正常。2.2.2 打包设置进入项目设置 - 打包。将内容目录包含在非UFS中Windows这个选项通常需要勾选它会把Content目录下的资源文件打包进.pak文件而不是散落在各个目录。对于专用服务器虽然它不渲染资源但仍需要加载材质、网格体等资源的元数据以及蓝图类信息因此通常也需要打包资源。不过你可以通过后续的烹饪Cook设置来优化。使用Pak文件勾选。这是标准做法。生成块对于大型项目可以启用以支持流式下载。初期可以不勾。2.2.3 项目描述文件.uproject的修改你需要手动编辑项目根目录下的.uproject文件用记事本或VS Code等文本编辑器。在Modules数组后添加Targets配置明确告诉构建系统我们要生成哪些目标。{ FileVersion: 3, EngineAssociation: 5.3, Category: , Description: , Modules: [ { Name: YourProjectName, Type: Runtime, LoadingPhase: Default } ], Targets: [ { Name: YourProjectNameEditor, Platform: Win64, Configuration: DevelopmentEditor, TargetType: Editor }, { Name: YourProjectName, Platform: Win64, Configuration: Shipping, TargetType: Client }, { Name: YourProjectNameServer, Platform: Win64, Configuration: Shipping, TargetType: Server } ] }注意TargetType是关键。Client告诉引擎这是一个客户端构建目标Server则对应专用服务器。Shipping表示发行版配置它会最大化优化并移除调试信息。在开发阶段你可以先用Development配置打包以便出现问题时查看更详细的日志。2.3 构建目标文件的创建仅仅修改.uproject文件还不够我们还需要在源码层面创建对应的构建目标文件。如果你的项目是C项目或者你已通过“新建C类”将蓝图项目转换为C项目你需要在Source目录下进行操作。打开Source文件夹找到YourProjectName.Target.cs文件。这个文件通常已经存在它定义了客户端构建目标。复制该文件并重命名为YourProjectNameServer.Target.cs。打开YourProjectNameServer.Target.cs修改其类名和构造函数中的TargetType。// YourProjectNameServer.Target.cs using UnrealBuildTool; using System.Collections.Generic; public class YourProjectNameServerTarget : TargetRules { public YourProjectNameServerTarget(TargetInfo Target) : base(Target) { Type TargetType.Server; // 关键修改将 TargetType.Game 改为 TargetType.Server DefaultBuildSettings BuildSettingsVersion.V2; ExtraModuleNames.AddRange( new string[] { YourProjectName } ); // 如果是专用服务器通常不需要渲染器可以关闭以减小体积和依赖 bBuildWithEditorOnlyData false; bCompileWithPluginSupport true; // 强制链接核心模块避免服务器因缺少客户端模块而编译失败 bForceBuildTargetPlatforms true; } }这个文件告诉Unreal Build Tool (UBT)当构建YourProjectNameServer这个目标时请按照“服务器”的规则来编译它会自动排除掉客户端专用的模块如Slate UI渲染、音频混合器等从而生成一个更精简的可执行文件。3. 服务端专属逻辑与资源处理专用服务器不需要渲染因此我们需要在代码和资源管理上做一些特殊处理以确保服务器程序不会尝试加载或执行客户端独有的功能这能显著减少打包体积并避免运行时崩溃。3.1 使用WITH_SERVER_CODE和G_IS_SERVER宏在C代码中最常用的方法是使用预编译宏来区分服务器和客户端代码。WITH_SERVER_CODE: 这个宏在编译服务器目标时定义为1编译客户端目标时为0。你可以用它来包裹只在服务器上需要的代码。G_IS_SERVER(或IsRunningDedicatedServer()): 这是一个运行时检查。在代码中你可以用if (G_IS_SERVER)或if (IsRunningDedicatedServer())来判断当前是否运行在专用服务器环境下。实操示例避免服务器加载UI假设你有一个在玩家出生时创建用户界面的函数void AMyCharacter::BeginPlay() { Super::BeginPlay(); // 只在非专用服务器即客户端或监听服务器上创建UI if (!IsRunningDedicatedServer()) { CreatePlayerHUDWidget(); } // 服务器和客户端都需要执行的逻辑比如注册到游戏管理器 RegisterWithGameMode(); }资源引用隔离在蓝图中也要注意。如果一个Actor的蓝图里引用了复杂的粒子系统或高清纹理并且这个Actor会在服务端生成那么这些资源仍然会被打包进服务器程序因为蓝图类需要被完整加载。虽然服务器不会渲染它们但磁盘空间被浪费了。最佳实践是为服务端使用的Actor创建简化版的蓝图移除所有视觉效果组件和引用。或者在C中动态加载资源时使用IsRunningDedicatedServer()判断避免在服务器上调用LoadObject加载贴图、材质等。3.2 烹饪设置为服务器优化资源“烹饪”是将项目资源uasset文件转换为平台特定格式的过程。我们可以为服务器配置独立的烹饪设置。打开项目设置 - 项目 - 打包找到高级区域点击烘焙修改器旁边的配置修改器。在弹出的ini编辑器中你可以添加针对服务器的烹饪规则。一个常见的需求是服务器不需要烹饪纹理、音效等媒体资源。你可以创建一个DefaultServer.ini文件保存在Config目录下内容如下; Config/DefaultServer.ini [/Script/UnrealEd.ProjectPackagingSettings] DirectoriesToAlwaysCook(Path/Game/Assets/Textures) DirectoriesToAlwaysCook(Path/Game/Assets/Sounds) ; 这里不是排除而是列出需要烹饪的。更常见的做法是在打包命令行中指定。更实用的方法是通过命令行参数来控制。在打包时我们可以指定-targetplatformWindowsServer并使用-ini:Game来传递特定的配置。不过UE5更主流的方式是通过“烹饪过滤器”来精确控制。我的经验是对于中小型项目最简单的优化是在服务器的目标CS文件中设置bBuildWithEditorOnlyData false这能防止大量编辑器用的数据被打包进去。对于资源只要确保蓝图逻辑正确服务器不主动加载视觉资源那么即使这些资源被打包进去影响也有限主要是磁盘空间。优先保证功能正确优化可以后续进行。3.3 网络地址与端口配置服务端和客户端如何发现彼此你需要一个明确的地址和端口。命令行启动参数这是最灵活的方式。你可以在快捷方式或启动脚本中为服务器指定端口。服务端启动命令示例YourProjectNameServer.exe -log -port7777 -queryport27015 -multihome0.0.0.0-port: 游戏通信端口默认7777。-queryport: Steam或游戏服务器查询端口用于服务器浏览器。-multihome0.0.0.0: 绑定到所有网络接口允许任何IP的客户端连接。-log: 输出日志到控制台和文件便于调试。配置文件你可以在Saved/Config/WindowsServer目录下创建Engine.ini或Game.ini使用[/Script/OnlineSubsystemUtils.IpNetDriver]段来配置端口。但命令行参数的优先级更高。客户端连接在客户端中你需要提供连接逻辑。可以是一个UI输入框让玩家输入服务器IP:Port或者在代码里硬编码一个测试地址。连接的核心是调用UEngine::Browse或使用USession接口。4. 分步打包实操全流程现在我们进入实战环节。我将以在Windows平台上打包Windows版客户端和服务器为例演示两种主要方法使用Unreal Editor图形界面和使用命令行更推荐用于自动化。4.1 方法一使用Unreal Editor UI打包这种方法直观适合初次尝试或快速测试。项目准备确保你的项目已成功编译对于C项目并且在编辑器内以“专用服务器”模式测试通过在编辑器下拉菜单中选择“专用服务器”然后点击播放。打开打包设置在Unreal Editor中点击菜单栏的平台-Windows-打包项目设置...。这里可以设置输出目录、是否生成Chunks等。通常保持默认即可。打包客户端再次点击平台-Windows。选择打包项目-你的项目名称Win64。引擎会开始烹饪资源并打包最终在项目目录/Saved/StagedBuilds/Windows下生成一个包含YourProjectName.exe客户端的文件夹。注意这样打包出来的是客户端。要打包服务器UI界面没有直接选项。打包服务器通过UI变通方法在编辑器主界面的“平台”下拉菜单旁边有一个“配置”下拉菜单默认是“开发”。将其改为“发布”。然后在“平台”-“Windows”下可能会出现打包项目-你的项目名称服务器Win64的选项。但请注意这个选项并不总是稳定出现取决于引擎版本和项目配置。更可靠的方法是使用方法二命令行。实操心得UI打包服务器非常不直观且容易失败。我强烈建议一旦你确认了项目配置正确就立即转向命令行打包。命令行不仅稳定而且参数清晰易于集成到CI/CD持续集成/部署流程中。4.2 方法二使用命令行打包推荐这是生产环境的标准做法。你需要打开“Visual Studio Developer Command Prompt”或任何配置了UE4/UE5构建工具的命令行环境。生成项目文件如果尚未生成或修改了.build.cs文件cd /d D:\YourUnrealProject D:\UE_5.3\Engine\Build\BatchFiles\RunUAT.bat BuildCookRun -projectD:\YourUnrealProject\YourProject.uproject -noP4 -platformWin64 -clientconfigShipping -serverconfigShipping -server -nocompile -cook -allmaps -build -stage -pak -archive -archivedirectoryD:\Output这个命令看起来很复杂我们来拆解一下RunUAT.bat: Unreal Automation Tool自动化构建的核心工具。-project: 指定你的.uproject文件路径。-platformWin64: 目标平台。-clientconfigShipping和-serverconfigShipping: 分别指定客户端和服务器的构建配置为“发行版”。-server:关键参数告诉UAT需要构建服务器目标。-cook: 烹饪资源。-allmaps: 烹饪所有地图。你也可以用-map指定特定地图。-build: 编译代码。-stage: 将构建好的文件复制到临时目录StagedBuilds。-pak: 将资源打包成.pak文件。-archive和-archivedirectory: 将临时目录的文件压缩归档到指定输出目录。分步执行与调试如果上面的完整命令失败了可以分步执行便于定位问题。只编译RunUAT.bat BuildCookRun -project... -build -skipcook -skipstage -skipdeploy -nop4只烹饪RunUAT.bat BuildCookRun -project... -cook -skipbuild -skipstage -skipdeploy -nop4只打包RunUAT.bat BuildCookRun -project... -stage -pak -archive -skipbuild -skipcook -skipdeploy -nop4输出结果成功执行后在D:\Output你指定的目录下你会找到两个子文件夹例如WindowsClient和WindowsServer。WindowsClient里是YourProjectName.exeWindowsServer里是YourProjectNameServer.exe。4.3 打包后的目录结构解析了解打包后的目录结构对部署和排查问题很有帮助。客户端目录 (WindowsClient) 典型结构WindowsClient/ ├── YourProjectName.exe # 主客户端程序 ├── YourProjectName/Binaries/Win64/... # 依赖的DLL ├── YourProjectName/Content/... # 游戏资源可能在Paks文件夹内 ├── YourProjectName/Saved/... # 运行后生成的存档、配置、日志 ├── Engine/... # 引擎运行时文件 └── .pak 文件 # 烹饪后的资源包服务器目录 (WindowsServer) 典型结构WindowsServer/ ├── YourProjectNameServer.exe # 主服务器程序 ├── YourProjectNameServer/Binaries/Win64/... # 服务器专用DLL体积更小 ├── YourProjectName/Content/... # 必要的游戏资源蓝图、数据表等 ├── Engine/... # 精简版的引擎运行时 └── .pak 文件 # 仅包含服务器所需资源的包如果优化过关键区别服务器目录中没有Slate、SlateRHIRenderer、AudioMixer等客户端渲染和音频相关的模块DLLEngine目录下的文件也更少。这是通过在Target.cs中设置Type TargetType.Server实现的。5. 部署、测试与问题排查指南打包成功只是第一步让服务端和客户端真正跑起来并互联才是最终考验。5.1 服务端部署与启动环境准备将WindowsServer整个文件夹复制到你的服务器机器上可以是另一台PC、虚拟机或云服务器。确保该机器安装了对应版本的Visual C 可再发行组件包通常来自WindowsServer\Engine\Extras\Redist\en-us下的UEPrereqSetup_x64.exe。防火墙设置在服务器防火墙中开放你指定的端口如7777TCP/UDP 和27015UDP。具体步骤因操作系统而异。启动服务器创建一个启动脚本StartServer.bat内容如下echo off cd /d %~dp0 start MyGameServer YourProjectNameServer.exe -log -port7777 -queryport27015 -multihome0.0.0.0双击运行此批处理文件。你会看到一个控制台窗口弹出显示日志。当看到LogNet: GameNetDriver IpNetDriver_0 listening on port 7777和LogLoad: LoadMap: L_ServerStartup类似的日志时说明服务器已成功启动并加载地图。5.2 客户端连接测试在另一台机器上运行客户端程序YourProjectName.exe。在游戏主菜单你需要实现一个“连接服务器”的功能。一个简单的测试方法是使用UE5控制台。在游戏中按~键Tab上方呼出控制台。输入命令open 192.168.1.100:7777将IP替换为你的服务器内网IP。如果网络通畅且服务器运行正常客户端应该会连接到服务器并开始加载地图。5.3 常见问题与排查技巧实录即使严格按照步骤操作也难免会遇到问题。下面是我在多次打包部署中积累的“避坑”经验。问题1打包失败提示“无法找到目标”或编译错误。排查首先检查.uproject文件中的Targets配置和Source目录下的.Target.cs文件名称、类名是否一致且正确。确保项目是C项目有Source文件夹纯蓝图项目无法生成独立的服务器目标需要先“创建C类”来添加基础代码模块。日志查看项目目录/Saved/Logs下的日志文件搜索 “Error” 或 “fatal”。编译错误通常会在这里有详细描述。问题2服务器启动后立即崩溃或客户端连接时崩溃。排查这是最常见的问题通常是因为服务器加载了客户端独有的资源或执行了客户端逻辑。检查日志服务器崩溃会在其目录下生成Saved/Logs日志。客户端崩溃也有自己的日志。仔细阅读崩溃前的最后几行。常见罪魁祸首蓝图中的“Begin Play”事件检查所有可能在服务端生成的Actor的蓝图其“Begin Play”中是否包含了生成粒子、播放音效、创建Widget等操作。用Is Dedicated Server节点进行分支判断。C构造函数或BeginPlay如前所述用IsRunningDedicatedServer()进行保护。资源引用一个在服务端和客户端都存在的Actor蓝图如果其组件引用了超高分辨率的纹理或复杂材质虽然服务器不渲染但默认仍会尝试加载其数据。确保这些资源本身没有问题无损坏。调试技巧先用-Development配置打包服务器和客户端。这样生成的可执行文件包含调试符号崩溃时能给出更清晰的调用栈。在服务器启动命令中加入-crash参数可以生成更详细的崩溃报告。问题3客户端能连接到服务器但卡在加载界面或进入后所有角色不动。排查这是网络同步问题。端口问题确认客户端连接的端口与服务器监听的端口一致。使用netstat -ano | findstr :7777命令在服务器上检查端口是否确实在监听。防火墙/路由器如果服务器在公网或不同子网确保路由器已设置端口转发Port Forwarding。网络复制检查你的游戏角色、道具等关键Actor是否设置了bReplicates true移动组件是否开启了复制。在服务器控制台输入debug.net.simulate相关命令可以观察网络流量。问题4打包出来的服务器程序体积过大。优化方向检查Target.cs确认bBuildWithEditorOnlyData false。分析Cooked资源使用Unreal Insights或查看烹饪报告项目目录/Saved/Cooked/WindowsServer/AssetRegistry.bin分析哪些资源被打包了。考虑将服务器绝对用不到的材质、纹理、音效移动到单独的目录并在打包设置中排除。使用Staged Build分析工具引擎提供了UnrealPak工具可以列出.pak文件内容分析哪些资源占用了大量空间。问题5在非Windows平台如Linux上打包服务器。要点Linux是更常见的服务器操作系统。UE5支持交叉编译Linux服务器。你需要安装Linux交叉编译工具链在Epic Games Launcher的引擎版本详情中勾选。在打包命令中将-platformWin64改为-platformLinux。服务器目标文件YourProjectNameServer.Target.cs中的Target平台检测逻辑可能需要调整通常使用(Target.Platform UnrealTargetPlatform.Linux)进行条件编译。部署到Linux服务器后记得给可执行文件添加权限chmod x YourProjectNameServer.sh通常还会生成一个shell脚本。打包和部署UE5的DS服务端与客户端是一个将开发成果转化为可交付产品的关键步骤。这个过程充满了细节和陷阱但一旦你完整地走通几次并理解了每一步背后的原理它就会变成一项稳定可靠的例行工作。记住耐心查看日志、分步测试先本地后远程、先开发配置后发行配置、以及为服务器和客户端做好清晰的逻辑隔离是成功的关键。

相关新闻