🚀 30+款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度
这次我们来看一个面向实习或毕业设计的实战项目:基于 Linux 服务器部署,并使用 Mirror 组件实现网络同步的 Unity 游戏。对于很多 Unity 开发者来说,从单机游戏到支持多人在线的网络游戏是一道坎,而 Mirror 作为 Unity 生态中一个成熟、开源且易于上手的网络库,是很多人的首选。但如何将开发好的 Mirror 游戏,特别是服务器端,部署到 Linux 服务器上稳定运行,并确保网络同步稳定,这个过程涉及不少细节。
本文的核心就是解决这个问题。我们将围绕一个典型的实习作品或毕业设计项目,拆解从 Unity 编辑器内开发测试,到最终将服务器构建为 Linux 可执行文件并部署到云服务器的完整流程。重点不是 Mirror 的基础 API 调用,而是如何打通“开发-构建-部署-运维”这条链路,让你能真正拥有一个可对外提供服务的网络游戏服务器。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 项目类型 | Unity 多人游戏服务器(使用 Mirror 网络库)的 Linux 部署方案 |
| 核心组件 | Unity Engine, Mirror Networking API, Unity Transport Package (UTP) |
| 服务器环境 | Linux 发行版(如 Ubuntu 20.04/22.04),无需图形界面 |
| 部署方式 | 通过 Unity 交叉编译生成 Linux 服务器可执行文件,通过 SSH/SCP 上传至服务器运行 |
| 网络同步 | 基于 Mirror 实现游戏状态(位置、动画、属性等)在客户端与服务器间的同步 |
| 服务管理 | 可使用 systemd 或 Supervisor 将服务器进程作为后台服务管理,实现开机自启、崩溃重启 |
| 适合场景 | 毕业设计、实习作品、小型多人游戏项目、网络编程学习、Linux 服务部署实践 |
| 前置知识 | 基础的 Unity 使用、C# 编程、Linux 命令行操作、网络基础概念 |
2. 适用场景与使用边界
这个部署方案主要适用于以下几种情况:
- 教育与实践:非常适合计算机相关专业的学生,用于完成包含网络模块的毕业设计或实习作品。它能完整展示从开发到部署的全栈能力。
- 原型与测试:对于独立开发者或小团队,在游戏早期原型阶段,需要快速搭建一个可公开测试的服务器环境,验证网络玩法和同步逻辑。
- 轻量级游戏服务:适用于玩家数量不多(如几十人同时在线)、游戏逻辑相对简单的休闲、棋牌或小房间制游戏。
需要注意的使用边界:
- 性能上限:此方案基于 Mirror 和 Unity 内置的序列化/反序列化。对于需要极高频同步(如 FPS 射击游戏)或海量实体(如 MMO)的场景,可能需要更底层的网络库和更复杂的架构优化。
- 安全考虑:Mirror 提供了基础的 RPC 和 SyncVar 同步,但游戏逻辑的安全性(如防作弊)需要开发者自行在服务器端严格校验。直接部署的服务器暴露在公网,需注意防火墙、DDoS 基础防护等安全配置。
- 服务治理:本文方案侧重于“让服务器跑起来”。对于生产环境,还需要考虑日志收集、监控告警、自动伸缩、负载均衡等更高级的运维功能,这些需要额外的工具和架构设计。
3. 环境准备与前置条件
在开始构建和部署之前,请确保你的开发环境和目标服务器环境满足以下条件。
开发机(Windows/macOS)环境:
- Unity Hub & Unity Editor:安装 Unity Hub,并通过它安装一个Unity 2020.3 LTS 或更高版本的编辑器。LTS 版本长期支持,更适合部署。
- Unity 项目:一个已经使用 Mirror 网络库开发了基本多人游戏功能的 Unity 项目。确保网络逻辑(如移动同步、生成玩家、RPC 调用)在编辑器内通过 Host(主机)模式测试通过。
- Linux 构建模块:在 Unity Hub 中,为你安装的 Unity 编辑器版本添加Linux Build Support (Mono)模块。这是交叉编译 Linux 版本的关键。
- 打开 Unity Hub -> 选择已安装的版本 -> 点击右侧齿轮图标 -> “添加模块” -> 勾选 “Linux Build Support (Mono)” 并安装。
目标 Linux 服务器环境:
- 操作系统:推荐使用Ubuntu 20.04 LTS 或 22.04 LTS。这是云服务商最常见的镜像,社区支持完善。
- 基础工具:确保服务器已安装
ssh、scp(用于文件传输)、screen或tmux(用于会话管理,可选但推荐)。 - 运行依赖:Unity 构建的 Linux 独立应用通常需要一些基础库。在 Ubuntu 上,通常需要安装以下包:
如果运行时提示缺少其他库,可以根据错误信息再行安装。sudo apt update sudo apt install -y libgtk-3-0 libasound2 libnss3 libxss1 libxtst6 xdg-utils - 网络与防火墙:
- 确保服务器的安全组/防火墙规则开放了你的游戏服务器监听的端口(例如 Mirror 默认的
7777端口,或你在代码中指定的端口)。 - 如果你使用云服务器,通常还需要在云服务商的控制台配置安全组规则。
- 确保服务器的安全组/防火墙规则开放了你的游戏服务器监听的端口(例如 Mirror 默认的
4. 在 Unity 中配置项目与构建 Linux 服务器
这一步的目标是生成一个可以在 Linux 上运行的、无图形界面的服务器可执行文件。
4.1 配置构建目标与参数
- 在 Unity 编辑器中打开你的项目。
- 点击菜单栏File -> Build Settings。
- 在Platform列表中,选择Linux。如果未显示,请返回“环境准备”部分检查是否安装了 Linux 构建模块。
- 在左下角,勾选 “Server Build”选项。这是最关键的一步,它告诉 Unity 构建一个无图形界面的、专用于服务器运行的程序。
- 在Target Architecture中,根据你的服务器 CPU 架构选择。大多数云服务器是x86_64。
- (可选)配置Player Settings:
- 点击Player Settings按钮。
- 在Resolution and Presentation下,可以禁用 “Run In Background” 以外的所有全屏/窗口设置,因为服务器不需要显示。
- 在Scripting Backend中,确保为Mono(如果你安装了 Mono 支持)。IL2CPP 通常能获得更好的性能,但构建时间更长,且可能需要处理额外的依赖。
- 点击Build或Build And Run,选择一个本地目录(如
Builds/LinuxServer)来保存构建输出。
构建完成后,你会在目标目录下看到类似以下结构的文件:
LinuxServer/ ├── UnityPlayer.so ├── Server.x86_64 # 这是主要的可执行文件 ├── Server_Data/ │ ├── Managed/ │ ├── Resources/ │ └── ... └── MonoBleedingEdge/ # 或类似名称的运行时目录关键点:Server.x86_64就是你的服务器程序。整个LinuxServer文件夹需要完整上传到 Linux 服务器。
4.2 处理 Unity 服务(如 Relay)
如果你的项目使用了 Unity Relay 服务(用于 NAT 穿透),构建服务器时需要注意:
- 服务器构建通常不需要 Relay:Relay 主要用于帮助客户端之间建立 P2P 连接或连接到一个非专用服务器(Listen Server)。对于部署在云上的专用服务器(Dedicated Server),它拥有公网 IP 和固定端口,客户端可以直接连接,一般无需 Relay。
- 代码适配:确保你的网络管理器代码(如
NetworkManager或自定义的MyNetworkManager)在构建服务器时,不会尝试初始化或连接 Relay 服务。可以通过#if UNITY_SERVER预编译指令来区分服务器和客户端的逻辑。
// 在你的网络管理器中 public override void OnStartServer() { base.OnStartServer(); #if !UNITY_SERVER // 客户端或主机模式下的逻辑,例如初始化Relay InitializeRelayIfNeeded(); #endif // 服务器专用初始化逻辑 StartGameServerLogic(); }5. 部署到 Linux 服务器并运行
我们将把构建好的文件夹上传到服务器,并以一种稳定的方式运行它。
5.1 上传文件到服务器
使用scp命令(在本地终端或 PowerShell 中执行)将整个构建文件夹上传到服务器:
# 假设你的服务器IP是 123.123.123.123,用户名是 ubuntu # 将本地 Builds/LinuxServer 目录上传到服务器的 /home/ubuntu/game_server 目录 scp -r /path/to/your/local/Builds/LinuxServer ubuntu@123.123.123.123:/home/ubuntu/game_server输入服务器密码后,文件开始传输。如果文件较多,传输可能需要一些时间。
5.2 在服务器上运行游戏服务器
通过 SSH 连接到你的 Linux 服务器:
ssh ubuntu@123.123.123.123进入上传的目录,并运行服务器程序:
cd /home/ubuntu/game_server/LinuxServer # 赋予可执行文件运行权限 chmod +x Server.x86_64 # 直接运行(前台运行,关闭SSH会终止进程) ./Server.x86_64如果一切正常,你应该能在终端看到 Unity 服务器的启动日志,最后可能停留在类似Started server on port 7777的提示上。
第一次运行可能遇到的问题:
- 权限不足:
chmod +x命令已解决。 - 缺少动态库:如果提示
error while loading shared libraries: libxxx.so.x,请根据错误信息安装对应的库。例如,libgtk-3-0等。 - 端口被占用:如果默认的 7777 端口被占用,你可以在启动时指定端口:
同时,确保你的游戏客户端连接代码也指定了相同的端口。./Server.x86_64 -port 8888
5.3 使用 Screen/Tmux 进行会话管理(推荐)
直接在前台运行服务器,SSH 断开连接后进程就会终止。使用screen或tmux可以创建持久化的会话。
使用 Screen:
# 1. 安装 screen (如果未安装) sudo apt install screen # 2. 创建一个新的 screen 会话,命名为 “gameserver” screen -S gameserver # 3. 在新会话中启动服务器 cd /home/ubuntu/game_server/LinuxServer ./Server.x86_64 -logfile server.log # 将日志输出到文件 # 4. 暂时离开会话,按 Ctrl+A,然后按 D # 此时服务器在后台继续运行 # 5. 重新连接到会话 screen -r gameserver # 6. 要结束会话,先连接进去,然后停止服务器(如按 Ctrl+C),最后输入 exit使用 Tmux:
# 1. 安装 tmux sudo apt install tmux # 2. 创建并进入新会话 tmux new -s gameserver # 3. 启动服务器 cd /home/ubuntu/game_server/LinuxServer ./Server.x86_64 -logfile server.log # 4. 分离会话,按 Ctrl+B,然后按 D # 5. 重新连接 tmux attach -t gameserver # 6. 结束会话,在会话内停止服务器后,输入 exit 或按 Ctrl+D5.4 配置为 Systemd 服务(生产环境推荐)
对于需要开机自启、自动重启的正式部署,使用systemd是更规范的方式。
创建服务配置文件:
sudo nano /etc/systemd/system/unity-gameserver.service写入以下配置内容(根据你的路径修改):
[Unit] Description=Unity Game Server (Mirror) After=network.target [Service] Type=simple User=ubuntu WorkingDirectory=/home/ubuntu/game_server/LinuxServer ExecStart=/home/ubuntu/game_server/LinuxServer/Server.x86_64 -batchmode -nographics -logfile /home/ubuntu/game_server/server.log Restart=on-failure RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target-batchmode:以批处理模式运行,不弹出对话框。-nographics:不初始化图形设备,节省资源。-logfile:将日志重定向到指定文件,方便查看。
启用并启动服务:
sudo systemctl daemon-reload sudo systemctl enable unity-gameserver.service sudo systemctl start unity-gameserver.service查看服务状态和日志:
sudo systemctl status unity-gameserver.service sudo journalctl -u unity-gameserver.service -f # 实时查看日志
6. 客户端连接测试与网络同步验证
服务器部署并运行成功后,最关键的一步是验证客户端能否连接,并且网络同步是否正常工作。
6.1 构建并运行客户端
- 回到你的 Unity 编辑器,在Build Settings中,将平台切换回Windows、macOS或你需要的客户端平台,并取消勾选 “Server Build”。
- 构建出客户端程序。
- 在客户端程序中,修改连接服务器的地址和端口为你 Linux 服务器的公网 IP 和端口(例如
123.123.123.123:7777)。这通常在你的客户端连接 UI 代码中设置。// 例如,在Mirror的NetworkManagerHUD或自定义UI中 networkAddress = "123.123.123.123"; networkPort = 7777; - 运行客户端,尝试连接到服务器。
6.2 验证同步功能
连接成功后,进行以下测试来验证 Mirror 的同步机制:
- 玩家生成同步:多个客户端连接后,观察每个客户端场景中是否都正确生成了其他玩家的角色。
- 位置与移动同步:控制一个玩家角色移动,在其他客户端上观察该角色的位置和移动是否平滑、准确地同步。
- 动画状态同步:如果角色有跑、跳、攻击等动画,测试这些动画的触发和状态是否在所有客户端同步。
- RPC 调用:测试一个客户端发起的 RPC(如发送聊天消息、释放技能),检查服务器和其他客户端是否能正确接收和执行。
- SyncVar 同步:测试使用
[SyncVar]标记的变量(如玩家血量、分数)在发生变化时,是否自动同步到所有客户端。
观察服务器日志:在服务器上通过tail -f server.log或journalctl -f查看日志,确认客户端的连接、断开以及关键的游戏事件日志。
7. 性能监控与资源占用观察
对于一个小型实习作品或毕业设计,性能可能不是首要问题,但了解如何观察资源占用是很好的实践。
查看进程状态:
# 查看服务器进程的PID、CPU和内存占用 top -p $(pgrep -f Server.x86_64) # 或者使用 htop (需安装) htop监控网络连接:
# 查看服务器监听的端口和活跃连接 sudo netstat -tulpn | grep :7777 # 或使用 ss 命令 sudo ss -tulpn | grep :7777分析日志文件:定期检查
server.log文件,关注是否有异常错误、警告,以及连接数、帧率(如果服务器有逻辑帧)等信息。
典型资源占用:一个简单的、没有复杂物理和大量 AI 的 Mirror 服务器,在空闲状态下可能只占用几十 MB 内存和很少的 CPU。当有玩家连接并进行游戏时,CPU 和内存占用会上升,具体取决于游戏逻辑的复杂度和玩家数量。对于毕业设计级别的项目,1核2G的云服务器通常绰绰有余。
8. 常见问题与排查方法
在部署和运行过程中,你可能会遇到以下问题:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 构建失败,找不到 Linux 目标 | Unity 未安装 Linux Build Support 模块。 | 检查 Unity Hub 中对应编辑器版本的已安装模块。 | 通过 Unity Hub 添加 “Linux Build Support (Mono)” 模块。 |
| 服务器程序在 Linux 上无法启动,提示权限不足 | 可执行文件没有执行权限。 | 运行ls -l Server.x86_64查看权限。 | 执行chmod +x Server.x86_64。 |
| 启动失败,提示缺少共享库 (.so 文件) | 系统缺少 Unity 运行时依赖的库。 | 查看具体的错误信息,通常是libxxx.so.x: cannot open shared object file。 | 使用apt search libxxx查找并安装对应的包。常见依赖见“环境准备”部分。 |
| 客户端无法连接到服务器 | 1. 服务器进程未运行。 2. 防火墙/安全组未开放端口。 3. 客户端连接地址/端口错误。 4. 服务器程序绑定了 127.0.0.1而非0.0.0.0。 | 1. 在服务器上 `ps aux | grep Server确认进程。<br>2. 在服务器本地curl localhost:7777测试(可能无响应,但看能否连接)。<br>3. 检查客户端代码中的networkAddress和networkPort。<br>4. 检查 MirrorNetworkManager` 或传输层配置。 |
| 连接成功,但同步延迟高或卡顿 | 1. 服务器带宽不足或网络延迟高。 2. 游戏逻辑每帧同步数据量过大。 3. 服务器 CPU 负载过高。 | 1. 使用ping和traceroute测试网络。2. 检查代码中 Update里是否频繁调用Cmd/Rpc或修改大量SyncVar。3. 使用 top命令查看服务器资源。 | 1. 考虑升级服务器带宽或选择离玩家更近的地域。 2. 优化网络消息频率和大小,使用插值和外推平滑客户端表现。 3. 优化服务器端游戏逻辑代码。 |
| 服务器运行一段时间后崩溃 | 1. 内存泄漏(未销毁的网络对象等)。 2. 未处理的异常。 3. 系统资源耗尽。 | 1. 分析崩溃前的日志 (server.log)。2. 检查 Unity 玩家日志中是否有堆栈跟踪。 | 1. 确保网络对象在断开连接或游戏结束时被正确销毁 (NetworkServer.Destroy)。2. 在服务器代码中添加全局异常捕获和日志记录。 3. 使用 systemd的Restart=on-failure自动重启。 |
| 使用 Relay 时,服务器构建连接失败 | 服务器构建可能错误地调用了需要图形界面或特定平台的 Relay 初始化代码。 | 检查服务器启动日志,看是否有关于 UnityServices 初始化或身份验证的错误。 | 使用#if !UNITY_SERVER预编译指令将 Relay 相关的初始化代码包裹起来,确保服务器构建不执行它们。 |
9. 最佳实践与使用建议
为了让你的项目更稳健、更易于维护,可以参考以下建议:
- 版本控制与构建自动化:将构建脚本(如命令行调用 Unity 进行构建)纳入版本控制(如 Git)。可以使用 Jenkins、GitHub Actions 等 CI/CD 工具,在代码提交后自动构建 Linux 服务器和客户端。
- 配置分离:不要将服务器 IP、端口等配置硬编码在代码中。使用
ScriptableObject、JSON 配置文件或环境变量来管理,便于在不同环境(开发、测试、生产)间切换。 - 完善的日志系统:除了 Unity 自带的
Debug.Log,可以集成像log4net或Serilog这样的日志框架,将日志按级别(Info, Warning, Error)输出到文件,并设置日志轮转,避免日志文件过大。 - 实现状态监控:可以创建一个简单的 HTTP 健康检查端点(例如使用
UnityWebRequest创建一个监听本地端口的简单服务器),或者输出一个包含当前玩家数、游戏状态等信息的状态文件。外部监控工具可以通过检查这个端点或文件来判断服务器是否存活。 - 备份与回滚:在更新服务器程序前,备份旧版本和重要的玩家数据(如果有)。如果新版本出现问题,可以快速回滚到旧版本。
- 安全第一:
- 服务器端校验:所有重要的游戏逻辑(如伤害计算、物品获取)都必须在服务器端执行和校验,客户端只负责发送意图和表现。
- 输入验证:对客户端发送的所有数据进行验证,防止恶意数据包导致服务器崩溃或逻辑错误。
- 限制连接:根据服务器性能,设置最大连接数,防止资源被耗尽。
将 Unity Mirror 游戏部署到 Linux 服务器,是一个将开发成果转化为真实可服务产品的关键步骤。这个过程不仅涉及 Unity 构建选项的配置,更涵盖了 Linux 系统操作、网络运维和基础服务管理的知识。对于实习或毕业设计而言,成功完成部署并让同学或老师能够从外网连接到你的游戏进行体验,无疑会为你的作品增色不少。建议从简单的游戏原型开始实践,先确保“跑通”,再逐步深入优化和加固。
🚀 30+款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度