> For the complete documentation index, see [llms.txt](https://docs.edgegap.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.edgegap.com/zh/unreal-engine.md).

# Unreal Engine - 入门指南

通过实践学习，并在 Edgegap 上部署你的第一个专用服务器。本指南结束时，你将免费使用 Edgegap 部署一个专用服务器。

使用 Docker Desktop 构建是入门最快、最简单且最可靠的方法。

{% embed url="<https://youtu.be/q7ljcr9rAWE>" %}

## ✔️ 准备工作

<details>

<summary><a href="https://www.docker.com/products/docker-desktop/">安装 Docker Desktop 和 Docker Edgegap 扩展</a></summary>

* [从官方来源安装 Docker Desktop](https://www.docker.com/products/docker-desktop/) （无需账号）。
* 安装完成后重启电脑。
* 前往 设置 ⚙️ > 扩展 > 启用 Docker 扩展。
* [从官方 Docker 市场安装扩展（点击此链接）。](https://www.docker.com/products/docker-desktop/)

</details>

<details>

<summary><a href="https://open.docker.com/extensions/marketplace?extensionId=edgegap/docker-extension">安装 Edgegap Quickstart Docker 扩展</a></summary>

* 从 Docker Desktop / Extensions / Browse 安装，或者 [使用链接](https://open.docker.com/extensions/marketplace?extensionId=edgegap/docker-extension).

<figure><img src="/files/c050c0756c6591bb5539e2f537f5688f8fec0aaa" alt=""><figcaption></figcaption></figure>

</details>

{% hint style="info" %}
**对你的服务器构建有信心？** 跳到 [#customize-server-image](#customize-server-image "mention") 以及 [高级功能](/zh/learn/advanced-features.md).
{% endhint %}

## ⚙️ 1. 配置项目 <a href="#id-1-configure-project" id="id-1-configure-project"></a>

{% hint style="info" %}
这种方法无需下载 Unreal Engine 源码，也无需从源码构建！
{% endhint %}

☑️ 先 **验证你的 Unreal Engine 版本** - 已根据你的项目文件预填值。

☑️ **输入 GitHub 用户名和** [**PAT**](#user-content-fn-1)[^1] 来自 [#preparation](#preparation "mention")，用于从 GitHub 下载依赖项。

## 🔧 2. 构建游戏服务器 <a href="#id-2-build-game-server" id="id-2-build-game-server"></a>

现在我们将构建并烹饪你的项目，并将其打包为一个易于复用的 Docker 镜像。

☑️ 你可以配置以下选项（或保留默认值）：

* **镜像名称** 是你自定义的唯一标识，用于在发布前标记你的服务器构建。
  * 通常会包含你的游戏名称——例如“my-game-server”。
* **镜像标签** 是指向你镜像某个特定版本的标识。
  * “构建产物”这一术语有时也用于指代你镜像的特定版本。
  * 时间戳是一个很好的标签选项，例如 `2024.01.30-16.23.00-UTC`  （默认）。

☑️ **构建项目** 当你对配置满意后即可进行。完成此步骤后，你的本地 Docker 客户端中将新增一个包含 Linux 游戏服务器可执行文件的新镜像。

✅ 现在你可以进入下一步了。

## 🧪 3. 在本地测试服务器 <a href="#id-3-test-server-locally" id="id-3-test-server-locally"></a>

☑️ **选择你希望在本地运行的镜像标签** （远程镜像将会被下载）。可选地，还可以添加更多 [docker run 参数](https://docs.docker.com/reference/cli/docker/image/build/#options) 来定制你的本地测试：

* `-p 7777:7777/udp` - 这是你本地容器的 [端口映射](/zh/learn/bian-pai/application-and-versions.md#port-mapping),
* `-e ARBITRIUM_PORT_GAMEPORT_INTERNAL=7777`  是一个 [环境变量](#environment-variables) 用于模拟真实的 Edgegap 部署，告诉你的游戏服务器用于监听玩家连接的内部端口。

☑️ 当你对配置满意后，点击 **启动本地服务器**。完成此步骤后将会 **启动一个新的容器** 在你的开发机器上。

☑️ 现在该把你的 Unreal Engine 编辑器（PIE）游戏客户端连接到本地服务器容器了。使用 `~`  打开 Unreal PIE 控制台（波浪号键）并连接： `open <ip>:<port>`:

* `ip`  = `localhost`  或 `127.0.0.1`  （在大多数情况下等价），
* `port`  = Docker GUI 中容器随机分配的外部端口值。

✅ 现在你可以进入下一步了。

<details>

<summary>故障排查和常见问题</summary>

无法将客户端连接到服务器 - `请求超时。` , `请求超时` , `连接失败` ，或 `端口验证失败`

* 首先，确保容器已启动，并且日志中没有运行时错误。
* 请验证你在 `docker run` 命令中的端口值是否一致。
* 请确保你的游戏客户端连接的是 **外部端口** ，该值显示在你的容器详情页上，出于安全原因，这个值始终会随机生成。
* 请确保你已按步骤所述重命名目标文件并配置游戏构建 [#id-1-configure-project](#id-1-configure-project "mention").

***

我的容器已启动，但在之后的几分钟内我仍然无法连接。

* 容器启动后，你的游戏引擎初始化就会开始。这个过程可能从几秒到几分钟不等，在此期间服务器不接受玩家连接。
* 可以考虑优化服务器初始化，以缩短这段时间。
* 游戏客户端应以 1 秒间隔重试连接一段有限的时间（取决于你的初始化时长），之后应返回匹配流程。
* 可以考虑添加一个加载场景，这样服务器可以在与客户端同步状态的同时进行初始化（在 Unreal Engine 中还可完成地图切换）。

***

`警告：无法为绑定地址创建 socket`

* 请通过 Fab 资源商店安装 Epic 的 Steam Subsystem 插件。
* 当使用从 github 下载的 SteamCore 源码版本的 Edgegap Integration Kit（EGIK）时，由于 Epic Games 的插件分发政策，不包含 Epic 的 Steam Subsystem 插件。

***

我已连接，但屏幕完全是黑的。

* 请确认你设置了正确的 **游戏默认地图** ，位于 **编辑 / 项目设置 / 地图与模式**.

</details>

## ☁️ 4. 发布到 Edgegap <a href="#id-4-publish-to-edgegap" id="id-4-publish-to-edgegap"></a>

☑️ **选择一个应用名称** 用于在 Edgegap 上标记和分组相似镜像。

☑️ **选择你希望发布的镜像标签** 以及 **上传镜像**。完成此步骤后，你的服务器镜像将上传到 Edgegap Registry，并在浏览器中创建一个新的 [应用版本](/zh/learn/bian-pai/application-and-versions.md) 。 **请务必创建你的** [**端口映射**](/zh/learn/bian-pai/application-and-versions.md#port-mapping) **当提示时，** 使用默认&#x503C;**.**

{% hint style="success" %}
发现了 bug，需要再次重新构建/发布？请使用 **从源码重新构建** 以便 [#id-2.-build-game-server](#id-2.-build-game-server "mention") 以及 [#id-4.-publish-to-edgegap](#id-4.-publish-to-edgegap "mention") **快速使用当前扩展输入值进行操作。**
{% endhint %}

✅ 现在你可以进入下一步了。

## 🚀 5. 部署到云端 <a href="#id-5-deploy-to-cloud" id="id-5-deploy-to-cloud"></a>

☑️ 现在我们将进行最后的测试，并 **将你的 Unreal Engine 编辑器连接到云端部署**。请获取你的 **部署主机** ，替换服务器 IP 和部署的 **外部端口**，在游戏客户端中打开 Unreal 控制台（波浪号 `~`）并输入 `open {host}:{port}` .

<details>

<summary>故障排查和常见问题</summary>

无法将客户端连接到服务器 - `请求超时。` , `请求超时` , `连接失败` ，或 `端口验证失败`

* 首先，确保部署状态为 Ready，并且部署日志中没有运行时异常或错误。如果你的部署已停止，请在我们的 [仪表板](https://app.edgegap.com/deployment-management/deployments/list).
* 请验证你服务器构建的网络代码设置中的端口配置是否与你的 [应用版本](https://app.edgegap.com/application-management/applications/list)中的内部端口一致。对于插件构建，端口会自动为你设置。你可以通过编辑 [应用版本](https://app.edgegap.com/application-management/applications/list) 而无需重新构建。请在你的网络代码集成中查找协议。
* 请确保你的游戏客户端连接的是 **外部端口** ，该值显示在你的部署详情页上，出于安全原因，这个值始终会随机生成。
* 请确保你已按步骤所述重命名目标文件并配置游戏构建 [#id-1.-configure-project](#id-1.-configure-project "mention").
* 你是否位于中国并正在使用 [智能舰队](https://docs.edgegap.com/docs/deployment/session/fleet-manager/fleet)？你的连接可能会被防火长城阻止。可以考虑在你的舰队中添加位于中国的服务器，或者使用 VPN 连接。

***

我的部署已就绪，但之后的几分钟内我仍然无法连接。

* 一旦部署进入 Ready 状态，你的游戏引擎初始化就会开始。这个过程可能从几秒到几分钟不等，在此期间服务器不接受玩家连接。
* 可以考虑优化服务器初始化，以缩短这段时间。
* 游戏客户端应以 1 秒间隔重试连接一段有限的时间（取决于你的初始化时长），之后应返回匹配流程。
* 可以考虑添加一个加载场景，这样服务器可以在与客户端同步状态的同时进行初始化（在 Unreal Engine 中还可完成地图切换）。

***

`警告：无法为绑定地址创建 socket`

* 请通过 Fab 资源商店安装 Epic 的 Steam Subsystem 插件。
* 当使用从 github 下载的 SteamCore Integration Kit（SIK）源版本的 Edgegap Integration Kit（EGIK）时，由于 Epic Games 的插件分发政策，不包含 Epic 的 Steam Subsystem 插件。

***

我已连接，但屏幕完全是黑的。

* 请确认你设置了正确的 **游戏默认地图** ，位于 **编辑 / 项目设置 / 地图与模式**.
* 请确认 [Unreal Engine 版本兼容性检查已被禁用](#id-2.-configure-game-server-builds) 在 `DefaultEngine.ini`.

***

我的部署已停止/重启，而且我再也无法访问它的日志了。

* 如果服务器进程因异常而崩溃，我们的系统会尝试自动重启服务器。建议先在本地测试服务器，以找出根本原因。
* 我们只会在部署期间保留日志；如果你希望在部署停止后查看日志，请 [集成第三方日志存储](https://docs.edgegap.com/docs/deployment/endpoint-storage).
* 参见 [/pages/5e7e2169ca3822647d4607dfc1d3487ebcc0836c#id-5.-deployment-stopped](https://docs.edgegap.com/zh/pages/5e7e2169ca3822647d4607dfc1d3487ebcc0836c#id-5.-deployment-stopped "mention") 以了解导致部署停止的所有原因。

***

我的部署在 X 分钟后自动停止了。

* 免费层部署有 60 分钟限制，请考虑升级你的账户。
* 根据我们的服务器清理政策、为了基础设施维护，以及防止在部署未正确关闭时产生意外费用，所有部署在运行 24 小时后都会终止。对于长时间运行的服务器，请考虑使用 [私有舰队](/zh/learn/bian-pai/si-you-jian-dui.md) 配合 [持久化](/zh/learn/bian-pai/chi-jiu-hua.md).
* 参见 [/pages/5e7e2169ca3822647d4607dfc1d3487ebcc0836c#id-5.-deployment-stopped](https://docs.edgegap.com/zh/pages/5e7e2169ca3822647d4607dfc1d3487ebcc0836c#id-5.-deployment-stopped "mention") 以了解导致部署停止的所有原因。

***

如果玩家离开我的部署，会发生什么？

* 默认情况下，服务器不会拒绝玩家连接。玩家认证由你的开发者自行处理，因为可以使用许多不同的方法和玩家认证提供商。
* 游戏客户端可能会在本地存储连接信息，以便在客户端意外崩溃时尝试重新连接。
* 若想允许玩家加入进行中的游戏，可以考虑使用 [深入了解](/zh/learn/pi-pei/matchmaker-in-depth.md#backfill) 或 [会话](https://docs.edgegap.com/docs/deployment/session).

***

我的服务器在变为就绪后显示 100% CPU 占用。

* 这可能并不是问题，因为游戏引擎在服务器初始化期间往往会执行 CPU 密集型操作。如果在部署开始后的 2-3 分钟内 CPU 使用率没有下降，你可能需要优化服务器或增加应用版本资源。
* 降低 tick rate 有助于通过减少处理消息的数量来控制 CPU 使用率。
* 在免费层中，你的资源限制为 1.5 vCPU 和 3GB 内存（RAM）。
* 你可以在创建新应用版本时增加分配的资源。你也可以在我们的仪表板中复制你的应用版本并按需调整这些值，而无需重新构建服务器或镜像。

***

我的部署反复重启并显示错误 `OOM kill`

* 这是由于超出了分配的内存量。可以考虑使用对象池、压缩，或移除场景中不需要的对象来优化内存使用。
* 在免费层中，你的资源限制为 1.5 vCPU 和 3GB 内存（RAM）。
* 你可以在创建新应用版本时增加分配的资源。你也可以在我们的仪表板中复制你的应用版本并按需调整这些值，而无需重新构建服务器或镜像。

***

有时，我服务器的内存（RAM）使用量会猛增到很高，这有问题吗？

* 只要你没有超过分配给应用版本的内存量，这就不是问题。
* 超过分配给应用版本的内存量将导致 `OOM kill` （见上文）。

***

我的服务器性能会受到同一台机器上运行的其他服务器影响吗？

* 不会，我们的平台可确保分配的资源不会被其他工作室或共享基础设施上的其他服务器使用。使用 Edgegap，不会有“噪声邻居”。

</details>

## 👉 下一步

### 停止部署

比赛结束（或玩家离开）后，可以停止你的部署以节省成本。 [空跑或仅部分填充会不必要地增加你的成本！](https://edgegap.com/blog/how-session-fill-rate-affects-your-multiplayer-hosting-costs)

如果你按照本指南并使用我们的 Docker 扩展进行了构建，你只需调用方法 `FGenericPlatformMisc::RequestExit` 。我们已经在打包镜像中添加了一个管理服务器进程的脚本，它会自动执行优雅的部署关闭。

若要自定义服务器生命周期管理，请修改我们的 [示例 `StartServer.sh`](https://github.com/edgegap/edgegap-unreal-buildutils/blob/main/StartServer.sh)  脚本。

{% hint style="info" %}
更希望从 Unreal 中管理生命周期？请参阅 [开发者工具](/zh/unreal-engine/developer-tools.md#integration-kit) 了解自停止 API 蓝图。
{% endhint %}

### 注入变量

通过访问注入的环境变量，可以读取有用的信息，如部署 ID、服务器 IP 地址、服务器位置等。每个部署会自动包含：

* [部署变量](/zh/learn/bian-pai/deployments.md#injected-environment-variables) - 由 Edgegap 自动提供，
* [匹配变量](/zh/learn/pi-pei/matchmaker-in-depth.md#injected-environment-variables) - 在使用时由 Edgegap 自动提供 [匹配](/zh/learn/pi-pei.md),
* [应用版本变量](/zh/learn/bian-pai/application-and-versions.md#injected-variables) - 由你配置的自定义键值对。

{% hint style="success" %}
导入我们的 [开发者工具](/zh/unreal-engine/developer-tools.md#integration-kit) 以便 **使用 Blueprints 轻松读取带类型的变量**.
{% endhint %}

### 服务器性能分析

要理解并优化 Edgegap 上的服务器性能问题，请探索 [部署](/zh/learn/bian-pai/deployments.md#container-logs), [部署](/zh/learn/bian-pai/deployments.md#container-metrics)，以及更多 [部署](/zh/learn/bian-pai/deployments.md#dashboard-monitoring) 你可使用的工具。

你还可以将现有的 Unreal Engine 性能分析工具与 Edgegap 一起使用：

* [在你的 Unreal Engine 服务器中配置跟踪](https://dev.epicgames.com/documentation/en-us/unreal-engine/developer-guide-to-tracing-in-unreal-engine) （内置和自定义事件）：
  * 使用 `-tracefile`将 trace 保存到服务器磁盘，然后上传到第三方存储并离线分析，
  * 或者使用 [部署](/zh/learn/bian-pai/deployments.md#port-mapping) 通过 UDP 协议为内部端口流式传输 `1981` 。
* 分析 [内存洞察](https://dev.epicgames.com/documentation/en-us/unreal-engine/memory-insights-in-unreal-engine) 以及 [网络洞察](https://dev.epicgames.com/documentation/en-us/unreal-engine/networking-insights-in-unreal-engine) 以及 [#optimize-server-builds](#optimize-server-builds "mention").

### 会话自动化

### 优化构建

**配置资源分块，以将仅客户端资产与服务器资产隔离开。**

* 探索 [资源分块技术和建议](https://dev.epicgames.com/documentation/en-us/unreal-engine/preparing-assets-for-chunking-in-unreal-engine) 由 Epic 提供。

**排除仅供客户端使用、且服务器运行不需要的资产和插件。**

* 了解 [构建时资源和插件排除](https://dev.epicgames.com/community/learning/tutorials/Kp1k/unreal-engine-build-time-asset-and-plugin-exclusion).

**检查你的内容烹饪策略。**

* 考虑使用 [按需烹饪（Cooking on the Fly，COTF）](https://dev.epicgames.com/documentation/en-us/unreal-engine/build-operations-cooking-packaging-deploying-and-running-projects-in-unreal-engine#cookonthefly) 以延迟烹饪客户端资源并加快服务器构建。

**实施关卡流式加载，以减少运行时内存负载。**

* 如果你的设计让玩家大多集中在同一个地图区域， [关卡流式加载可将服务器内存使用量减少](https://dev.epicgames.com/documentation/en-us/unreal-engine/level-streaming-in-unreal-engine) 60% 以上，并提升客户端性能！

**只包含服务器运行绝对需要的内容。**

* 将未使用的文件复制到镜像中会导致镜像臃肿、上传更慢、缓存更慢，以及整体服务器启动更慢。 [查看 Docker 镜像优化建议](https://docs.docker.com/build-cloud/optimization/#dockerignore-files).

<details>

<summary>示例 <code>.dockerignore</code> 文件以移除额外文件。</summary>

```docker
# 已编译的对象文件
*.slo
*.lo
*.o
*.obj

# 预编译头文件
*.gch
*.pch

# 已编译的动态库
*.so
*.dylib
*.dll

# Fortran 模块文件
*.mod

# 已编译的静态库
*.lai
*.la
*.a
*.lib

# 可执行文件
*.exe
*.out
*.app
*.ipa

# 这些项目文件可以由引擎生成
*.xcodeproj
*.xcworkspace
*.sln
*.suo
*.opensdf
*.sdf
*.VC.db
*.VC.opendb

# 预编译资源
**/SourceArt/**/*.png
**/SourceArt/**/*.tga

# 构建
**/Build/*

# 白名单 PakBlacklist-<BuildConfiguration>.txt 文件
!**/Build/*/
**/Build/*/**
!**/Build/*/PakBlacklist*.txt

# 不要忽略 Build 中的图标文件
!**/Build/**/*.ico

# 由编辑器生成的配置文件
**/Saved/*
**/Intermediate/*
**/DerivedDataCache/*
**/Binaries/*
**/Build/*
**/Releases/*
**/Packaged/*
```

</details>

**考虑使用** [**多阶段 Docker 构建（链接）**](https://docs.docker.com/build/building/multi-stage/)**.**

* 将大型服务器依赖项拆分到单独的镜像中，以便在多阶段构建中复用。Docker 会缓存每一层，并简单复用上一版本，除非明确指示，否则会跳过上传这一部分，从而为你节省带宽和等待上传完成的时间。
* 如果你不确定为什么某个 Dockerfile 命令会报错，可以尝试在本地调试。在问题发生前新建一个阶段（添加第二个 `FROM` 命令），使用 `--target` 指示构建过程停在有问题的阶段，然后 `docker exec -it {container} /bin/bash` 进入容器内的交互式终端。之后，你可以使用基础镜像中的 shell 命令进一步排查（例如 `top` 在 Ubuntu 上）。

### 自定义镜像

对于由于构建体积优化、额外依赖，或需要更复杂启动流程而希望对镜像拥有更多控制的用户，我们也支持添加你自己的 Dockerfile。接下来我们将分享一些“自己动手”的技巧和最佳实践。

[^1]: 个人访问令牌


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.edgegap.com/zh/unreal-engine.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
