320 lines
12 KiB
Markdown
320 lines
12 KiB
Markdown
# UE5 客户端手动操作指南
|
||
|
||
> 本指南对应 `ue_client/` 目录下已生成的所有代码和配置。
|
||
> 代码已写好,你只需要做编辑器里的点击操作。
|
||
> 遇到红色错误先看文末"常见问题"章节。
|
||
|
||
---
|
||
|
||
## 前置条件
|
||
|
||
| 软件 | 版本 | 下载地址 |
|
||
|------|------|---------|
|
||
| Unreal Engine | **5.3** | Epic Games Launcher → Library → 5.3 |
|
||
| Cesium for Unreal | 最新 | 直接在下一步从 Marketplace 安装 |
|
||
| Visual Studio | 2022 Community | visualstudio.microsoft.com(安装 C++ 游戏开发工作负载) |
|
||
|
||
> **注意**:Cesium for Unreal 必须先安装,否则代码会编译失败。
|
||
|
||
---
|
||
|
||
## 第一阶段(Phase A):本地演示版(不需要后端)
|
||
|
||
### 步骤 1:安装 Cesium for Unreal
|
||
|
||
1. 打开 **Epic Games Launcher**
|
||
2. 顶部切换到 **Unreal Engine** 选项卡
|
||
3. 左侧点击 **Fab**(原 Marketplace,已改名)→ 搜索 `Cesium for Unreal`
|
||
4. 点击 **免费获取**(Free),然后点击 **安装到引擎** → 选择 5.3
|
||
5. 等待安装完成
|
||
|
||
---
|
||
|
||
### 步骤 2:打开项目
|
||
|
||
1. 打开 **Epic Games Launcher** → **Unreal Engine** → **Library**
|
||
2. 找到 5.3,点击右侧 **Launch** 旁边的下拉箭头 → **Browse**
|
||
3. 导航到 `planet/ue_client/`,选择 `PlanetClient.uproject`,点击打开
|
||
4. UE 会提示"缺少模块,需要重新编译" → 点击 **Yes**
|
||
5. 等待编译完成(首次约 5-10 分钟)
|
||
|
||
> 如果编译报错:见文末"常见问题 → 编译错误"
|
||
|
||
---
|
||
|
||
### 步骤 3:创建新关卡
|
||
|
||
1. 菜单栏 → **File** → **New Level**
|
||
2. 选择 **Empty Level**(空关卡)
|
||
3. 保存:**File** → **Save Current Level As**
|
||
路径:`Content/Maps/`,名称:`EarthMap`
|
||
4. 点击 **Save**
|
||
|
||
---
|
||
|
||
### 步骤 4:添加 Cesium 地球
|
||
|
||
1. 顶部菜单栏 → **Cesium**(如果没有此菜单,说明插件未激活:Edit → Plugins → 搜索 Cesium → 勾选 Enable → 重启)
|
||
2. 在 Cesium 面板里点击 **Add Blank 3D Tiles Tileset** — 这会自动在场景里添加:
|
||
- `CesiumGeoreference` Actor
|
||
- `Cesium3DTileset` Actor(地球瓦片)
|
||
3. 再点击 **Add Cesium ion Bing Maps Aerial** 添加卫星影像底图(需要免费 Cesium ion 账号)
|
||
|
||
> 如果没有 Cesium ion 账号:Cesium 菜单 → Connect to Cesium ion → 注册免费账号
|
||
|
||
---
|
||
|
||
### 步骤 5:添加相机 Pawn
|
||
|
||
1. 菜单栏 → **Cesium** → 找到 **Dynamic Pawn**(名称可能是 `CesiumFlyToComponent` 相关的 Blueprint)
|
||
**或者**:Content Browser → 顶部搜索框输入 `DynamicPawn` → 找到插件内容里的 `DynamicPawn` → 拖入场景
|
||
2. 在 **Outliner** 面板里点击刚拖入的 `DynamicPawn`
|
||
3. 在 **Details** 面板里,找到 **Auto Possess Player** → 改为 **Player 0**
|
||
|
||
> 这样游戏启动时摄像机会自动使用这个可飞行的地球相机。
|
||
|
||
---
|
||
|
||
### 步骤 6:配置 GameMode
|
||
|
||
1. 菜单栏 → **Window** → **World Settings**(如果没有,也可以在 Details Panel 里找)
|
||
2. 在 **World Settings** 面板里找到 **Game Mode Override**
|
||
3. 点击下拉框 → 搜索 `PlanetGameMode` → 选择它
|
||
4. 找到 **Default Pawn Class** → 改为上一步拖入的 `DynamicPawn`
|
||
|
||
---
|
||
|
||
### 步骤 7:创建 ComputePoint Blueprint
|
||
|
||
这步把我写的 C++ 类包装成可以在编辑器里配置材质的 Blueprint。
|
||
|
||
1. **Content Browser** → 空白处右键 → **Blueprint Class**
|
||
2. 搜索父类:输入 `ComputePointActor` → 找到 `AComputePointActor` → 点击 **Select**
|
||
3. 命名为 `BP_ComputePointActor`,保存到 `Content/Blueprints/`
|
||
|
||
**配置 BP_ComputePointActor 的网格和材质:**
|
||
|
||
4. 双击打开 `BP_ComputePointActor`
|
||
5. 在左侧 **Components** 面板里点击 `SphereMesh`
|
||
6. 在右侧 **Details** 面板里找到 **Static Mesh** → 点击下拉 → 搜索 `Sphere` → 选择 **Engine/BasicShapes/Sphere**
|
||
7. 找到 **Material** → 点击下拉 → 搜索 `M_Basic_Wall` 或者创建新材质(见下方)
|
||
|
||
**创建三种状态的材质(颜色点即可):**
|
||
|
||
8. Content Browser → 右键 → **Material** → 命名 `M_PointNormal`
|
||
- 双击打开 → 右键空白区域 → 搜索 `Constant3Vector` → 连接到 `Base Color`
|
||
- 颜色设为橙色:`(1.0, 0.4, 0.0)`
|
||
- 保存
|
||
|
||
9. 同样方式创建 `M_PointHovered`(颜色白色 `1,1,1`)和 `M_PointSelected`(颜色青色 `0,1,1`)
|
||
|
||
**回到 BP_ComputePointActor:**
|
||
|
||
10. 在 **Details** 面板里:
|
||
- **Normal Material** → 选 `M_PointNormal`
|
||
- **Hovered Material** → 选 `M_PointHovered`
|
||
- **Selected Material** → 选 `M_PointSelected`
|
||
- **Point Scale** → `80000`(根据实际效果调整)
|
||
11. 点击左上角 **Compile** → **Save**
|
||
|
||
---
|
||
|
||
### 步骤 8:放置 DataManager 并配置
|
||
|
||
1. **Content Browser** → 右键 → **Blueprint Class** → 父类搜索 `PlanetDataManager` → 选择 `APlanetDataManager`
|
||
2. 命名为 `BP_PlanetDataManager`,保存到 `Content/Blueprints/`
|
||
3. 将 `BP_PlanetDataManager` **拖入场景**(Outliner 里会出现它)
|
||
4. 在 Outliner 里点击它 → 在 **Details** 面板里配置:
|
||
- **Use Local Mock Data** → ✅ **勾选**(Phase A 不需要后端)
|
||
- **Mock Data Path** → 留空(代码会自动找 `Content/Data/mock_compute_points.json`)
|
||
- **Compute Point Class** → 选择 `BP_ComputePointActor`
|
||
- **Point Altitude Meters** → `50000`(海拔 50km,可调)
|
||
|
||
---
|
||
|
||
### 步骤 9:测试 Phase A
|
||
|
||
1. 点击顶部工具栏绿色 **Play** 按钮(或 Alt+P)
|
||
2. 地球应该加载卫星影像
|
||
3. 应该看到 10 个橙色球体分布在地球上(对应 mock JSON 里的 TOP500 超算)
|
||
4. 鼠标移到球体上 → 变白色(Hover)
|
||
5. 点击球体 → 变青色(Selected)
|
||
|
||
**验证通过标准:**
|
||
- [x] 地球可见
|
||
- [x] 橙色球体出现在正确位置(美国、日本、荷兰、芬兰等)
|
||
- [x] 悬停变色
|
||
- [x] 点击变色
|
||
|
||
---
|
||
|
||
## 第二阶段(Phase B):连接真实后端
|
||
|
||
### 步骤 10:确认后端新接口可用
|
||
|
||
后端代码已添加新路由,先验证它已经运行:
|
||
|
||
```bash
|
||
# 在 WSL 或终端里
|
||
curl http://localhost:8000/api/v1/ue/status
|
||
```
|
||
|
||
应该返回类似:
|
||
```json
|
||
{"ok": true, "server_time": "...", "compute_points_count": 500, ...}
|
||
```
|
||
|
||
如果 curl 失败:
|
||
- 检查 `planet.sh` 是否在运行(`./planet.sh start`)
|
||
- 检查 WSL2 → Windows 的网络:在 UE 里使用 `172.x.x.x`(WSL 网关地址)而不是 `localhost`
|
||
|
||
---
|
||
|
||
### 步骤 11:获取 WSL2 → Windows 的正确 IP
|
||
|
||
在 WSL 终端里运行:
|
||
|
||
```bash
|
||
cat /etc/resolv.conf | grep nameserver | awk '{print $2}'
|
||
```
|
||
|
||
记下这个 IP(例如 `172.22.32.1`)。
|
||
|
||
---
|
||
|
||
### 步骤 12:切换 DataManager 到实时模式
|
||
|
||
1. 在 Outliner 里点击 `BP_PlanetDataManager`
|
||
2. Details 面板里:
|
||
- **Use Local Mock Data** → **取消勾选**
|
||
- **Backend Base URL** → 填入 `http://172.22.32.1:8000`(你的实际 WSL IP)
|
||
3. 重新 Play → DataManager 会通过 HTTP 拉取真实数据
|
||
|
||
---
|
||
|
||
### 步骤 13:绑定点击事件显示信息卡(可选,需要 UMG)
|
||
|
||
这步是可选的,需要创建一个 Widget Blueprint 来显示选中点的信息。
|
||
|
||
1. Content Browser → 右键 → **User Interface** → **Widget Blueprint**
|
||
2. 命名为 `WBP_PointInfo`
|
||
|
||
**设计 Widget 布局:**
|
||
|
||
3. 双击打开 `WBP_PointInfo`
|
||
4. 从左侧 **Palette** 拖入以下控件到画布:
|
||
- `Canvas Panel`(容器,设置为全屏)
|
||
- `Border`(右下角定位,用作信息卡背景,宽 300,高 200)
|
||
- `Text Block` × 4(名称、排名、算力、国家)
|
||
|
||
**绑定事件(Blueprint 里操作):**
|
||
|
||
5. 打开 `BP_PlanetDataManager` 的 Event Graph
|
||
6. 找到 **BeginPlay** 节点
|
||
7. 拖出线 → 搜索 **Bind Event to On Point Selected**(这是我在 PlayerController 里定义的委托)
|
||
|
||
> 具体蓝图连线:从 PlayerController 获取 OnPointSelected → Bind → 在回调里 Create Widget WBP_PointInfo → Add to Viewport → Set 各个文本
|
||
|
||
---
|
||
|
||
## 文件结构总览
|
||
|
||
```
|
||
ue_client/
|
||
PlanetClient.uproject ← UE 项目入口
|
||
Config/
|
||
DefaultGame.ini ← GameMode 配置
|
||
DefaultEngine.ini ← 渲染/引擎设置
|
||
DefaultInput.ini ← 键鼠输入绑定
|
||
Content/
|
||
Data/
|
||
mock_compute_points.json ← Phase A 本地测试数据(10个超算)
|
||
Maps/
|
||
EarthMap.umap ← 你在步骤3创建的关卡
|
||
Blueprints/
|
||
BP_ComputePointActor ← 步骤7创建
|
||
BP_PlanetDataManager ← 步骤8创建
|
||
Source/
|
||
PlanetClient/
|
||
PlanetClient.Build.cs ← 模块依赖(HTTP、JSON、Cesium)
|
||
PlanetClient.h/.cpp ← 模块入口
|
||
PlanetDataTypes.h ← 数据结构定义(FComputePoint 等)
|
||
PlanetDataManager.h/.cpp ← HTTP 拉取 + 生成 Actor
|
||
ComputePointActor.h/.cpp ← 单个超算点的可视化 Actor
|
||
PlanetPlayerController.h/.cpp ← 鼠标点击、悬停、相机控制
|
||
PlanetGameMode.h/.cpp ← GameMode 入口
|
||
```
|
||
|
||
---
|
||
|
||
## 后端新接口一览
|
||
|
||
后端已新增以下接口(无需认证,直接访问):
|
||
|
||
| 接口 | 说明 |
|
||
|------|------|
|
||
| `GET /api/v1/ue/status` | 健康检查 + 各数据源数量 |
|
||
| `GET /api/v1/ue/compute-points` | TOP500 超算数据(平铺 JSON) |
|
||
| `GET /api/v1/ue/landing-points` | 海缆登陆点(平铺 JSON) |
|
||
| `GET /api/v1/ue/cables` | 海缆路由几何(segments 数组) |
|
||
| `GET /api/v1/ue/satellites` | 卫星 TLE 数据 |
|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### Q: 编译报错 "Cannot open include file: CesiumGeoreference.h"
|
||
**A:** Cesium for Unreal 没有正确安装,或者没有在 `.uproject` 里启用。检查:
|
||
1. Epic Launcher → 插件是否安装到 5.3
|
||
2. `PlanetClient.uproject` 里 `Plugins` 数组是否有 `CesiumForUnreal: true`
|
||
3. UE 编辑器 → Edit → Plugins → 搜索 Cesium → 确认已勾选 Enabled
|
||
|
||
### Q: Play 之后没有看到橙色球体
|
||
**A:** 按以下顺序排查:
|
||
1. Output Log(Window → Output Log)里搜索 `PlanetDataManager` — 查看是否有报错
|
||
2. 检查 `BP_PlanetDataManager` 的 Details → **Compute Point Class** 是否已设置为 `BP_ComputePointActor`
|
||
3. 检查 **Mock Data Path** 是否正确(留空则自动用 `Content/Data/mock_compute_points.json`)
|
||
4. 检查 **Use Local Mock Data** 是否已勾选
|
||
|
||
### Q: 地球是灰色的没有卫星影像
|
||
**A:** 需要 Cesium ion 账号:
|
||
1. Cesium 菜单 → Connect to Cesium ion
|
||
2. 注册免费账号并授权
|
||
3. 重新添加 **Cesium ion Bing Maps Aerial** tileset
|
||
|
||
### Q: WSL2 里的后端 UE 无法访问(Phase B)
|
||
**A:** WSL2 和 Windows 是不同网络命名空间。方法:
|
||
1. 在 WSL 里运行 `ip route show default | awk '{print $3}'` — 这是 Windows 主机的 IP
|
||
2. 后端绑定到 `0.0.0.0:8000`(检查 `uvicorn` 启动参数,应已如此配置)
|
||
3. 在 UE 的 DataManager 里填写这个 IP 而不是 `localhost`
|
||
|
||
### Q: TransformLongitudeLatitudeHeightPositionToUnreal 不存在
|
||
**A:** Cesium for Unreal API 在不同版本有变化。如果编译报此错,将 `PlanetDataManager.cpp` 里的调用改为:
|
||
```cpp
|
||
// Cesium for Unreal v1.x 的旧 API:
|
||
FVector WorldPos = Georeference->TransformLongitudeLatitudeHeightToUnreal(
|
||
Pt.Longitude, Pt.Latitude, PointAltitudeMeters);
|
||
|
||
// 或者通过 GeoTransforms:
|
||
#include "CesiumGlobeAnchorComponent.h"
|
||
// ... 见 Cesium 文档
|
||
```
|
||
|
||
### Q: 点击球体没有反应
|
||
**A:**
|
||
1. 确认 `SphereMesh` 上 **Collision Presets** 不是 `NoCollision`
|
||
- 打开 `BP_ComputePointActor` → 点击 `SphereMesh` → Details → Collision → 改为 `BlockAllDynamic`
|
||
2. 确认 PlayerController 的 `bEnableClickEvents = true`(代码里已设置)
|
||
3. Output Log 里搜索是否有输入相关报错
|
||
|
||
---
|
||
|
||
## 下一步(一期完成后)
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| 海缆路径渲染 | `/api/v1/ue/cables` 已就绪,需要在 UE 里用 Spline 绘制 |
|
||
| 信息卡 UMG | 创建 Widget Blueprint 并在 PlayerController OnPointSelected 里显示 |
|
||
| WebSocket 实时更新 | 后端已有 WebSocket,UE 端需要使用 WebSockets 插件 |
|
||
| 卫星轨迹 | TLE 数据已就绪,需要在 UE 里做轨道传播计算 |
|