news 2026/7/27 9:48:52

Unity Mirror游戏服务器Linux部署:从构建到运维完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Unity Mirror游戏服务器Linux部署:从构建到运维完整指南

在游戏开发领域,网络同步是多人联机游戏的核心技术挑战。对于使用 Unity 引擎的开发者而言,Mirror Networking 组件因其开源、高性能和与 Unity 原生网络 API 的高度兼容性,成为了构建中小型多人游戏的热门选择。然而,将基于 Mirror 开发的游戏从本地测试环境部署到 Linux 服务器上,并确保其稳定运行,是一个涉及开发、运维和网络知识的综合性任务。许多开发者能够在本机或局域网内实现流畅的同步,但一旦涉及公网服务器部署,便会遇到连接失败、延迟抖动、资源加载异常等一系列问题。

本文旨在为 Unity 开发者提供一个从零开始,将基于 Mirror 组件的游戏项目部署到 Linux 服务器的完整实践指南。我们将不仅关注部署步骤本身,更会深入解释每一步背后的原理、常见的配置陷阱以及生产环境下的最佳实践。无论你是正在准备实习作品的在校学生,还是希望将个人项目上线的独立开发者,通过本文,你将能够理解 Linux 服务器环境下的 Unity 游戏运行机制,掌握服务端构建、部署、监控和排错的完整流程,最终实现一个可对外提供稳定服务的游戏服务器。

1. 理解 Unity 与 Mirror 在服务器环境下的运行模式

在开始部署之前,必须明确 Unity 游戏在服务器端(通常称为“头显模式”或“服务器构建”)与客户端构建的本质区别。这决定了我们如何准备环境、构建项目以及配置运行参数。

1.1 Unity 服务器构建与客户端构建的核心差异

Unity 项目可以构建为多种目标平台。对于网络游戏,我们通常需要两个构建产物:

  1. 客户端构建:包含完整的图形界面、音效、用户输入处理等,运行在玩家的电脑或设备上。
  2. 服务器构建:通常是一个“无头”构建,意味着它不包含图形渲染、音频输出等与玩家直接交互的模块。它的核心职责是运行游戏逻辑、维护游戏状态、处理网络消息同步以及进行权威判定。

对于 Linux 服务器部署,我们生成的就是服务器构建。Mirror 组件内部已经处理了网络消息的序列化、反序列化和路由,但服务器构建本身需要正确的 Unity 设置来剥离不必要的客户端开销。

关键配置点

  • 图形 API:服务器构建应禁用或选择最轻量的图形 API(如 Null),因为服务器不需要渲染。
  • 脚本后端:在 Linux 上,通常选择 Mono 或 IL2CPP。IL2CPP 能提供更好的性能和安全性(防反编译),但构建时间更长。
  • 目标架构:根据服务器 CPU 架构选择 x86_64(常见)或 ARM64。

1.2 Mirror 组件的网络同步模型与服务器角色

Mirror 支持多种网络拓扑,最常见的是客户端-服务器模型。在此模型中:

  • 服务器是游戏状态的权威来源。所有关键游戏逻辑(如玩家移动验证、伤害计算、物品生成)都在服务器上执行。
  • 客户端发送输入指令给服务器,并从服务器接收状态更新,然后在本地进行预测和插值以呈现平滑的画面。
  • NetworkManager:Mirror 的核心管理器,负责管理网络连接、玩家对象生成、场景切换等。在服务器构建中,NetworkManager必须存在并正确配置为以服务器模式启动。

理解这一点至关重要:部署到 Linux 服务器的,是一个包含了完整游戏逻辑、并以服务器模式运行的 Unity 程序。它通过 Mirror 监听特定端口,等待客户端连接并与之通信。

1.3 Linux 服务器环境的特点与要求

与 Windows 开发环境不同,生产级 Linux 服务器通常:

  • 无图形界面:通过 SSH 进行命令行操作。
  • 资源受限:CPU 和内存需要合理规划,尤其是同时运行多个游戏服务器实例时。
  • 权限严格:使用非 root 用户运行服务是基本安全要求。
  • 需要进程管理:服务器程序需要以守护进程形式运行,确保崩溃后能自动重启。
  • 依赖库:Unity IL2CPP 构建的 Linux 程序可能需要特定的系统库(如libc版本、libstdc++等)。

因此,我们的部署方案必须适应这些特点,确保游戏服务器稳定、安全且易于维护。

2. 环境准备与项目配置

一个成功的部署始于本地正确的项目配置。跳过或错误配置这一步,会导致构建出的服务器程序无法在 Linux 上运行。

2.1 本地 Unity 项目配置

首先,确保你的 Unity 项目已正确集成 Mirror。可以通过 Unity 的 Package Manager 或直接导入 Asset Store 包来完成。

  1. 安装 Mirror:通过 Window -> Package Manager -> Add package from git URL,输入https://github.com/vis2k/Mirror.git进行安装。
  2. 配置 NetworkManager:在场景中创建一个空对象,添加NetworkManagerKCPTelepathy传输层组件(Mirror 自带)。配置地址和端口(例如0.0.0.07777)。
  3. 设置玩家预制体:在 NetworkManager 的 Player Prefab 字段中,拖入你的玩家角色预制体。确保该预制体上有NetworkIdentity组件。

2.2 针对 Linux 服务器构建的 Player Settings

这是最关键的一步。打开 Project Settings -> Player。

  1. Resolution and Presentation
    • 取消勾选Run In Background(对于服务器,通常希望它一直运行,但也可勾选)。
    • Fullscreen Mode设置为WindowedExclusive FullScreen(对于无头模式影响不大,但建议设为 Windowed)。
  2. Icon:服务器构建不需要图标,可忽略。
  3. Splash Image:禁用所有闪屏图像以减少构建大小和启动干扰。
  4. Other Settings
    • Color Space:Linear 或 Gamma 对服务器逻辑无影响,但保持与客户端一致即可。
    • Auto Graphics API取消勾选。然后移除所有 Graphics APIs,或者只保留一个最轻量的如Vulkan(但服务器无需渲染)。更彻底的做法是后续通过命令行参数禁用。
    • Scripting Backend:选择IL2CPP。这是生产服务器的推荐选择,性能更好。
    • Api Compatibility Level.NET Standard 2.1.NET Framework(确保 Mirror 和你的代码支持)。
    • Allow ‘unsafe’ Code:根据你的代码需要决定。
    • Active Input Handling:设置为Input System Package (New)Both。即使服务器不需要输入,但某些插件可能依赖它。
    • Server Build必须勾选。这个选项会剥离大量客户端专用代码,显著减小构建体积并提升运行效率。
  5. Publishing Settings
    • Compression Method:选择LZ4HC以在构建大小和加载速度间取得平衡。对于服务器,资源包可能不是问题。

2.3 编写简单的服务器启动控制脚本

为了在无界面的 Linux 服务器上优雅地控制游戏服务器,我们需要一个启动脚本。这个脚本将处理启动、停止、重启以及日志记录。

创建一个名为game_server.sh的 Shell 脚本:

#!/bin/bash # 游戏服务器启动脚本 # 作者:Your Name # 描述:用于控制基于Mirror的Unity游戏服务器 SERVER_NAME="MyUnityGameServer" SERVER_DIR="/home/username/game_server" SERVER_EXEC="${SERVER_DIR}/MyUnityGameServer.x86_64" LOG_FILE="${SERVER_DIR}/logs/server_$(date +%Y%m%d_%H%M%S).log" PID_FILE="${SERVER_DIR}/server.pid" # 创建日志目录 mkdir -p "${SERVER_DIR}/logs" # 检查服务器可执行文件是否存在 if [ ! -f "$SERVER_EXEC" ]; then echo "错误:服务器可执行文件未找到在 $SERVER_EXEC" exit 1 fi start() { if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then echo "$SERVER_NAME 已经在运行 (PID: $(cat $PID_FILE))" exit 1 fi echo "正在启动 $SERVER_NAME ..." # 使用 nohup 在后台运行,并将输出重定向到日志文件 # -batchmode: Unity 无头模式,不弹出窗口,不等待用户输入 # -nographics: 完全禁用图形设备,节省资源 # -logFile: 指定 Unity 自身的日志输出位置 cd "$SERVER_DIR" nohup "$SERVER_EXEC" -batchmode -nographics -logFile "${SERVER_DIR}/unity.log" > "$LOG_FILE" 2>&1 & SERVER_PID=$! echo $SERVER_PID > "$PID_FILE" echo "$SERVER_NAME 已启动,PID: $SERVER_PID, 日志: $LOG_FILE" } stop() { if [ ! -f "$PID_FILE" ]; then echo "$SERVER_NAME 的PID文件未找到,可能未运行。" exit 1 fi PID=$(cat "$PID_FILE") echo "正在停止 $SERVER_NAME (PID: $PID) ..." kill $PID sleep 2 if kill -0 $PID 2>/dev/null; then echo "强制终止进程..." kill -9 $PID fi rm -f "$PID_FILE" echo "$SERVER_NAME 已停止。" } status() { if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then echo "$SERVER_NAME 正在运行 (PID: $(cat $PID_FILE))" else echo "$SERVER_NAME 未运行" rm -f "$PID_FILE" 2>/dev/null # 清理无效的PID文件 fi } case "$1" in start) start ;; stop) stop ;; restart) stop sleep 3 start ;; status) status ;; *) echo "使用方法: $0 {start|stop|restart|status}" exit 1 ;; esac

脚本关键参数解释

  • -batchmode:Unity 批处理模式,对于服务器构建至关重要。它使 Unity 以非交互方式运行,不会弹出任何窗口或对话框。
  • -nographics:完全禁用图形系统。这是服务器构建的推荐参数,能最大程度减少资源占用。
  • -logFile:指定 Unity 引擎自身日志的输出路径。这与我们脚本中nohup重定向的应用日志是分开的,便于分类排查问题。

3. 构建、传输与服务器环境配置

完成本地配置后,下一步是生成可执行文件并将其部署到 Linux 服务器。

3.1 在 Unity Editor 中构建 Linux 服务器

  1. 打开 File -> Build Settings。
  2. 在 Platform 列表中选择Linux
  3. 选择Target PlatformServer。这通常对应x86_64架构。
  4. 确保底部的Server Build复选框被勾选(应与 Player Settings 中的一致)。
  5. 点击Switch Platform,等待 Unity 重新编译相关资源。
  6. 点击Build,选择一个输出目录(如Builds/LinuxServer),并为可执行文件命名(例如MyUnityGameServer)。
  7. 构建完成后,你会在输出目录得到几个关键文件:
    • MyUnityGameServer.x86_64:主可执行文件。
    • MyUnityGameServer_Data/:包含游戏资源、代码库等。
    • UnityPlayer.so等共享库文件。

3.2 准备 Linux 服务器环境

假设你拥有一台运行 Ubuntu 20.04/22.04 LTS 的云服务器(如腾讯云、阿里云ECS)。

  1. 系统更新与基础工具

    sudo apt update && sudo apt upgrade -y sudo apt install -y wget curl tar unzip screen htop
  2. 创建专用用户(安全最佳实践):

    sudo adduser gameserver # 按照提示设置密码等信息 sudo usermod -aG sudo gameserver # 如果需要sudo权限来安装依赖 # 切换到该用户 su - gameserver
  3. 安装可能的依赖库:Unity IL2CPP 构建的 Linux 程序可能需要特定的库。一个常见的缺失库是libicu

    sudo apt install -y libicu-dev libgl1-mesa-glx

    如果运行时仍提示缺少库,可以使用ldd命令检查可执行文件的依赖:

    ldd MyUnityGameServer.x86_64

    根据缺失的.so文件(如libstdc++.so.6)安装对应的包(如libstdc++6)。

3.3 传输文件与目录结构

使用scprsync将本地构建的文件上传到服务器。建议在服务器上建立清晰的目录结构。

# 在本地终端执行 scp -r /path/to/local/Builds/LinuxServer/* gameserver@your_server_ip:/home/gameserver/game_server/

服务器上的理想目录结构:

/home/gameserver/ └── game_server/ ├── MyUnityGameServer.x86_64 # 主程序 ├── MyUnityGameServer_Data/ # 游戏数据 ├── UnityPlayer.so # Unity运行时库 ├── game_server.sh # 控制脚本 ├── config/ # (可选) 配置文件目录 │ └── server_config.json ├── logs/ # 日志目录 │ ├── server_20231027_1415.log │ └── unity.log └── server.pid # 运行后生成的PID文件

上传后,在服务器上为控制脚本添加执行权限:

chmod +x /home/gameserver/game_server/game_server.sh

4. 运行、验证与基础监控

现在,游戏服务器文件已就位,可以尝试启动并进行基础验证。

4.1 首次启动与基础验证

  1. 启动服务器

    cd /home/gameserver/game_server ./game_server.sh start

    使用status命令检查状态:

    ./game_server.sh status
  2. 检查日志:查看启动日志,确认没有致命错误。

    tail -f logs/server_20231027_1415.log tail -f unity.log

    关键日志信息

    • Server started on port 7777或类似信息,表明 Mirror NetworkManager 已成功监听端口。
    • 没有ExceptionError级别的日志。
    • 游戏初始化逻辑相关的日志正常输出。
  3. 验证网络监听:使用netstatss命令检查程序是否在监听配置的端口。

    sudo netstat -tulpn | grep :7777 # 或 sudo ss -tulpn | grep :7777

    应该能看到你的MyUnityGameServer.x86_64进程正在监听所有接口 (0.0.0.0:7777) 或特定接口。

4.2 从客户端进行连接测试

这是最直接的验证方式。在本地 Unity Editor 或已构建的客户端中,将NetworkManager的服务器地址修改为你的 Linux 服务器的公网 IP 地址,端口保持7777

  1. 客户端连接:运行客户端,尝试连接。
  2. 观察服务器日志:连接成功时,服务器日志应出现Client connected等信息。游戏内逻辑(如玩家生成)应正常执行。
  3. 测试基本同步:在客户端操作角色移动、攻击等,观察其他连接的客户端(或服务器日志)是否能正确同步这些动作。

4.3 使用 systemd 管理服务(生产环境推荐)

对于需要长期运行、开机自启的生产环境,使用systemd比简单的 Shell 脚本更可靠。它提供了强大的进程监控、日志集成和资源控制功能。

  1. 创建 systemd 服务文件

    sudo vim /etc/systemd/system/my-unity-game.service
  2. 编辑服务配置

    [Unit] Description=My Unity Game Server (Mirror) After=network.target [Service] Type=simple User=gameserver Group=gameserver WorkingDirectory=/home/gameserver/game_server ExecStart=/home/gameserver/game_server/MyUnityGameServer.x86_64 -batchmode -nographics -logFile /home/gameserver/game_server/logs/unity.log Restart=on-failure RestartSec=10 StandardOutput=journal StandardError=journal # 可选:限制资源 # LimitNOFILE=65536 # LimitNPROC=4096 [Install] WantedBy=multi-user.target

    注意:这里直接使用了可执行文件路径,而不是 Shell 脚本。systemd会自行管理进程和日志(通过journalctl)。Restart=on-failure确保了进程意外退出时会自动重启。

  3. 启用并启动服务

    sudo systemctl daemon-reload sudo systemctl enable my-unity-game.service sudo systemctl start my-unity-game.service
  4. 查看服务状态和日志

    sudo systemctl status my-unity-game.service sudo journalctl -u my-unity-game.service -f # 实时跟踪日志

5. 常见问题排查与解决方案

部署过程中难免会遇到问题。以下表格列出了基于 Mirror 的 Unity 游戏服务器在 Linux 部署时最常见的问题及其排查路径。

问题现象可能原因检查点与解决方案
服务器启动后立即退出1. 缺少系统依赖库。
2. Unity 构建时未勾选Server Build
3. 脚本运行时错误(如空引用)在Awake/Start中发生。
1. 检查unity.log文件末尾的堆栈跟踪。使用ldd检查依赖。
2. 确认 Unity Editor 和 Build Settings 中的Server Build均已勾选。
3. 在开发构建中启用Development BuildScript Debugging,获取更详细的错误信息。
客户端无法连接到服务器1. 服务器防火墙未开放端口。
2.NetworkManager地址绑定错误(如127.0.0.1)。
3. 云服务器安全组/网络ACL规则限制。
1.sudo ufw allow 7777(如果使用 UFW)。
2. 确认服务器上NetworkManagerNetwork Address0.0.0.0
3. 登录云控制台,检查安全组入方向规则是否允许 TCP/UDP 7777 端口。
连接成功但玩家无法移动或动作不同步1. 服务器和客户端预制体、脚本版本不一致。
2.NetworkIdentityAssetId冲突或为空。
3. 运动逻辑只在客户端执行,未通过[Command]发送到服务器。
1. 确保服务器和客户端使用完全相同的构建版本(包括所有预制体和脚本)。
2. 检查玩家预制体及其子物体上的NetworkIdentity组件是否有效(AssetId 不为空)。
3. 确认玩家移动代码使用了[Command]属性,并且是从拥有权限的客户端调用。
服务器运行一段时间后崩溃或卡死1. 内存泄漏(未销毁的网络对象、未取消的订阅事件)。
2. 逻辑死循环或性能热点。
3. 系统资源(内存、CPU)耗尽。
1. 使用htop监控内存增长。检查代码中NetworkServer.SpawnNetworkServer.Destroy的配对使用。
2. 在 Unity Profiler(连接远程)或通过简单日志计时定位性能瓶颈。
3. 使用systemdRestart策略,并考虑为服务设置资源限制 (LimitAS,LimitCPU)。
Linux 服务器上日志输出混乱或缺失1. 日志被输出到不同位置(控制台、文件、systemd journal)。
2. Unity 的Debug.Log在无头模式下行为差异。
1. 统一日志路径。使用-logFile参数指定 Unity 引擎日志,应用日志通过脚本重定向或由systemd管理。
2. 考虑使用更成熟的日志库(如SerilogNLog)并配置为同时输出到文件和控制台,确保在-batchmode下正常工作。
构建文件过大1. 未启用服务器构建,包含了所有客户端资源。
2.Development Build被启用,包含了调试符号。
3. 未使用适当的压缩方式。
1. 双重确认Server Build已勾选。
2. 发布构建时禁用Development Build
3. 在 Player Settings -> Publishing Settings 中使用LZ4HC压缩。

6. 生产环境最佳实践与进阶配置

当游戏服务器通过基础测试后,为了应对真实玩家负载和长期稳定运行,需要考虑以下进阶配置。

6.1 配置管理与环境变量

硬编码的配置(如端口号、数据库连接串)不利于维护。建议使用外部配置文件或环境变量。

  1. 创建 JSON 配置文件(config/server_config.json):
    { "serverPort": 7777, "maxPlayers": 100, "gameMode": "TeamDeathmatch", "logLevel": "Info" }
  2. 在 Unity 服务器启动代码中读取:可以在NetworkManagerStartAwake方法中,使用System.IO.File.ReadAllText读取并解析 JSON 文件。
  3. 使用环境变量:对于更敏感或动态的配置(如数据库密码),可以通过环境变量传递。
    # 在启动脚本或 systemd 服务文件中设置 export DB_PASSWORD="your_secure_password" ExecStart=/path/to/server ... -batchmode -nographics
    在 C# 代码中通过Environment.GetEnvironmentVariable("DB_PASSWORD")获取。

6.2 实现日志轮转与监控

日志文件会不断增长,需要定期归档或清理。

  1. 使用 logrotate(Linux 系统工具): 创建/etc/logrotate.d/my-unity-game

    /home/gameserver/game_server/logs/*.log { daily missingok rotate 7 compress delaycompress notifempty create 0640 gameserver gameserver sharedscripts postrotate # 如果使用 systemd,可以通知 journal 或重启服务(如果需要) # systemctl kill -s HUP my-unity-game.service 2>/dev/null || true endscript }

    这将每天轮转日志,保留最近 7 天的压缩副本。

  2. 基础资源监控:使用如Prometheus+Grafana或简单的node_exporter来监控服务器的 CPU、内存、网络和磁盘使用情况。对于游戏服务器,还可以自定义指标(如在线玩家数、每秒消息数)并通过 Mirror 的自定义消息或中间件暴露给监控系统。

6.3 安全加固建议

  1. 非 Root 用户运行:如前所述,始终使用gameserver这类低权限用户运行服务。
  2. 防火墙最小化:只开放游戏服务端口(如 7777)和必要的管理端口(如 SSH)。关闭所有其他不必要的端口。
  3. 定期更新:定期更新服务器操作系统、Unity 引擎版本和 Mirror 组件,以获取安全补丁。
  4. 防范 DDoS:对于公开服务器,考虑使用云服务商提供的 DDoS 基础防护,或集成专业的游戏盾服务。
  5. 验证与反作弊:服务器必须是所有游戏逻辑的权威。客户端发来的所有操作指令(如移动、使用技能)都必须在服务器端进行合法性验证(如坐标范围、冷却时间、资源消耗),而不能完全信任客户端。

6.4 性能调优考虑

  1. 传输层选择:Mirror 支持多种传输层。KCP 在丢包严重的网络环境下(如移动网络)表现优于默认的 Telepathy,但会消耗更多带宽和 CPU。根据你的游戏类型和玩家网络状况进行测试和选择。
  2. 网络更新频率:通过NetworkManagerSend Interval或自定义脚本调整状态同步的频率。更高的频率带来更流畅的体验,但也增加服务器和网络负担。
  3. 序列化优化:检查通过[SyncVar]或自定义网络消息同步的数据结构。避免每帧同步大量不变的数据,使用[SyncVar(hook = nameof(OnValueChanged))]来仅在值变化时触发更新。
  4. 服务器端视野管理:对于大型地图多玩家游戏,实现基于距离或区域的视野管理,只同步玩家附近的对象状态,可以大幅减少网络流量和服务器计算量。

将基于 Mirror 的 Unity 游戏部署到 Linux 服务器,是一个连接游戏开发与运维的实践过程。成功的关键在于清晰地理解服务器构建的本质、细致地完成每一步环境配置、并系统地建立部署后的监控与维护流程。从使用简单的启动脚本到集成 systemd 服务,从本地连接到公网测试,从解决依赖库问题到防范安全风险,每一步都需要以可复现、可排查的方式推进。

对于你的实习作品或个人项目,建议先从最小可行部署开始:确保最基本的连接和同步功能在服务器上稳定运行。然后,逐步引入配置文件、日志管理和进程守护。最后,再根据项目实际需求,考虑性能监控、自动化部署和水平扩展等更复杂的运维课题。记住,一个稳定、可观测的服务端,是任何多人联机游戏体验的基石。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/27 9:48:29

Java台球赛事报名系统开发与优化实践

1. 项目概述:Java台球赛事报名系统的核心价值 这个开源Java台球赛事报名系统为中小型台球俱乐部和赛事组织者提供了一个完整的数字化解决方案。我在实际部署测试中发现,它完美解决了传统纸质报名和Excel管理的三大痛点:信息混乱、统计困难和流…

作者头像 李华
网站建设 2026/7/27 9:48:11

Heimer思维导图软件终极指南:跨平台开源解决方案

Heimer思维导图软件终极指南:跨平台开源解决方案 【免费下载链接】Heimer Heimer is a simple cross-platform mind map, diagram, and note-taking tool written in Qt. 项目地址: https://gitcode.com/gh_mirrors/he/Heimer 在信息过载的数字化时代&#x…

作者头像 李华
网站建设 2026/7/27 9:47:37

C# Socket TCP客户端编程实战:异步通信、粘包处理与工业级实现

1. 项目概述:为什么选择C# Socket进行TCP通信? 在工业控制、物联网、游戏服务器、即时通讯等众多需要稳定数据交换的领域,TCP/IP协议栈是基石。作为一名长期奋战在一线的开发者,我处理过从简单的设备监控到复杂的分布式系统的各种…

作者头像 李华
网站建设 2026/7/27 9:47:11

SpringBoot智慧物业管理系统开发实践

1. 项目概述与行业背景智慧物业管理系统是当前社区数字化转型的核心载体。随着城市化进程加速和居民服务需求升级,传统物业模式正面临三大痛点:人工管理效率低下、服务响应滞后、数据孤岛严重。我们团队基于SpringBoot框架开发的这套社区智能化综合服务平…

作者头像 李华
网站建设 2026/7/27 9:45:19

如何打造专属虚拟伙伴:开源桌面宠物框架完整指南

如何打造专属虚拟伙伴:开源桌面宠物框架完整指南 【免费下载链接】DyberPet Desktop Cyber Pet Framework based on PySide6 项目地址: https://gitcode.com/GitHub_Trending/dy/DyberPet 想让喜欢的角色真正"活"在你的桌面上吗?厌倦了…

作者头像 李华