跳到主要内容

3D 导航:傻瓜式上手

照着点就能跑。本页讲 SDGToolSet 当前的 3D 导航玩法:放一个体积(Volume),让某个 Actor 沿自动生成的 3D 路径飞起来。

:::tip 必读前提 SDGToolSet 由 IADataSDG 的授权统一管控。IADataSDG 没激活,导航一律不动(路径不生成、Pawn 不飞、被指定的 Actor 也不动)。先看安装与激活。 :::

30 秒搞懂三种机制​

机制谁来驱动要不要 Pawn适用
A. 体积驱动指定 ActorUSDGNavDriverSubsystem(世界子系统,自动)不需要最简单:让任意 Actor 沿路径走
B. Pawn 跟随指定体积Pawn 上的 USDGPathManagerComponent需要飞行采集、相机巡航
C. 自动接管(旧行为,默认关)同 B,但自动扫描需要采集 Pawn BPP_Nav 的工作方式

两条铁律(避免“双重驱动”):

  1. 体积一旦设了 Navigated Actor,它就只由子系统驱动;任何 Pawn 都会跳过它。
  2. Pawn 只飞“没指定 Actor”的体积。两套机制的体积集合互不重叠,同一个体积/Actor 不会被驱动两次。

快速开始 A:放一个 Volume + 指定 Actor,让它自己走(最简单,无需 Pawn)​

  1. 放体积:打开 Place Actors(放置 Actor) 面板,搜索 SDG Nav Path Volume,拖进场景。
  2. 放大体积(关键一步):新放的体积默认只有约 200 × 200 × 200 cm,太小,生成不出路径。用缩放工具(快捷键 R)把它放大到能罩住一片开阔、无遮挡的可飞空间。参考示例关卡 Lv_TestToolSet 的大小约 2400 × 2350 × 450 cm(X × Y × Z);Z 就是飞行的高度带。把体积摆在没有墙体穿插的空中区域。
  3. 设体素大小:选中体积 → Details → 分类 SDG ▸ Grid → VoxelSize 填 100(cm,默认值;室内可 50~100)。务必远小于体积的最短边。
  4. 指定被导航的 Actor:Details → 分类 SDG ▸ PathGen → Navigated Actor,下拉选场景里任意一个 Actor(一个 Cube、StaticMeshActor、相机都行)。建议把它的 Mobility 设为 Movable;就算是静态根,系统也会在运行时自动提升为 Movable。
  5. 把它加入 IgnoreActors:Details → 分类 SDG ▸ NavPathVolume → IgnoreActors → 加一项,选刚才那个被导航的 Actor。否则它自己的碰撞会把体素堵住,路径可能绕不开自己。
  6. 按 Play(PIE)。

你应该看到:

  • 被指定的 Actor 先“瞬移”到路径起点,再沿平滑曲线飞行;
  • 飞到终点后停下(默认不循环);
  • Output Log 出现:
[SDG][NavDriver][VOL 0] Driving '<你的Actor>' along 1 spline(s).
[SDG][NavDriver] Self-driving 1 assigned-volume group(s).
[SDG][NavDriver] frame 0: '<你的Actor>' at (x, y, z)

不需要放 Pawn。USDGNavDriverSubsystem 在关卡 BeginPlay 时自动发现“带 Navigated Actor 的体积”,建路径并逐帧驱动。


快速开始 B:让一个 Pawn 跟随指定 Volume​

前提:目标体积的 Navigated Actor 必须留空(带指定 Actor 的体积由子系统接管,Pawn 会跳过)。

  1. 放体积:同 A 的第 1~3 步,但 Navigated Actor 留空。
  2. 放 Pawn:Place Actors 搜索 SDG Nav Path Pawn(类 ASDGNavPathPawn),拖进场景。它自带 PathManager 组件。
  3. 指定要飞的体积:选中 Pawn → Details → 找到 PathManager 组件 → 分类 SDG ▸ PathManager → FollowVolumes → 加一项,选第 1 步那个体积。
  4. 设速度:选中 Pawn → Details → 分类 Nav ▸ Move → MoveSpeed 填 400(cm/s)。bUsePIDController 默认关(匀速跟随);打开则用 PID 飞控。
  5. 按 Play。Pawn 会沿该体积的路径飞行,Output Log:
[SDG][PM] Explicit FollowVolumes: 1 volume(s) to fly.
[SDG][PM] RebuildPaths done: PawnSplines=1 AssignedVolumesSkipped=0 (driven by subsystem) TotalLen=...

:::note 用自己的 Actor + 组件时 如果你不用 ASDGNavPathPawn,而是给自己的 Actor 加 USDGPathManagerComponent 并调用 MoveInsideNavVolume() 驱动:注意 bUseProjectDefaults 默认 true,会在 BeginPlay 用项目设置覆盖你在 Details 里填的 MoveSpeed。要保留 per-instance 速度,把 bUseProjectDefaults 设为 false。 :::


机制 C(进阶,默认关):让 Pawn 自动接管所有“未指定”体积​

  • 选中 Pawn → PathManager → 分类 SDG ▸ PathManager → bAutoDiscoverUnassignedVolumes = true,并保持 FollowVolumes 为空。
  • 这样 Pawn 会飞场景里所有没有 Navigated Actor 的体积。这是采集 Pawn BPP_Nav 的工作方式。
  • 优先级:FollowVolumes 非空时永远优先用它(此时忽略 auto-discover)。

必填参数清单​

场景字段(Details 分类)必填?起始值一句话说明
全部IADataSDG 已激活✅ 必填—没激活则一切不动(授权门)
A / B体积尺寸✅ 必填~2400×2350×450 cm必须罩住开阔可飞空间;默认 200³ 太小
A / BVoxelSize(SDG ▸ Grid)✅ 必填100体素边长(cm),远小于体积最短边
ANavigated Actor(SDG ▸ PathGen)✅ 必填选一个 Actor谁来走这条路;留空=交给 Pawn
AIgnoreActors(SDG ▸ NavPathVolume)⭐ 强烈建议加入被导航 Actor防止它自己的碰撞堵住体素
BFollowVolumes(SDG ▸ PathManager)✅ 必填(B)加入目标体积Pawn 要飞哪些(仅“未指定”的体积)
BMoveSpeed(Nav ▸ Move,Pawn)可选400飞行速度(cm/s)
CbAutoDiscoverUnassignedVolumes(SDG ▸ PathManager)可选false开=飞所有未指定体积
通用bLoopAllPaths(SDG ▸ PathManager)可选false走完是否循环
通用bAutoAdvanceNext(SDG ▸ PathManager)可选true当前样条走完自动切下一条
通用RandomSeed(SDG ▸ PathGen)可选12345改变随机轨迹
通用bUseRandomPath(SDG ▸ PathGen)可选truetrue=随机起终点;false+自定义端点见下
通用NumPaths(SDG ▸ PathGen)可选1生成几条路径
通用bUseCustomEndpoints / CustomStart / CustomGoal(SDG ▸ PathGen)可选false指定固定起终点(需 bUseRandomPath=false)

机制 A 的飞行速度来自项目设置 → SDG Navigation 的 Movement.SpeedCmPerSec(默认 400 cm/s),不在体积上单独配。


如何开始测试​

编辑器内(PIE):直接点 Play。打开 Output Log(菜单 Window ▸ Output Log)核对:

  • 机制 A 成功:[SDG][NavDriver] Self-driving N assigned-volume group(s).
  • 机制 B 成功:[SDG][PM] RebuildPaths done: PawnSplines=N ...
  • 路径质量自检:[SDG][PM][VOL 0] PathClearance: 0/NN out-of-free (0.0%) Z[...] volZ[...]——越界比例越接近 0% 越好(说明路径没钻地/穿墙)。

命令行 / 无头(进阶):

"<UE_5.8>\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" "<你的工程>.uproject" <地图名> -game -windowed -log

不改关卡就换一条随机轨迹:追加 -dpcvars="sdg.nav.SeedOverride=24680"(≥0 时覆盖所有体积的 RandomSeed)。


排错 / 动不了怎么办​

症状关键日志解决
完全不动IADataSDG is not licensed/loaded; ... DISABLEDIADataSDG 没激活 → 先激活。激活后重进 PIE 即可,无需重启编辑器。
不动 / 没路径[SDG][NavDriver][VOL n] No navigable path generated ... Ensure the volume encloses free space and is at least a few VoxelSize across.(或 Pawn 侧 BuildVoxelGrid failed / PawnSplines=0)体积太小、没罩住空地,或 VoxelSize 太大 → 放大体积、确保罩住开阔空间、把 VoxelSize 调小。
Pawn 不动[SDG][PM] RebuildPaths done: PawnSplines=0 (no FollowVolumes, auto-discover OFF -> pawn flies nothing).Pawn 既没设 FollowVolumes,也没开 bAutoDiscoverUnassignedVolumes → 二选一配置。
Pawn 跳过了体积[SDG][PM][VOL n] Listed FollowVolume has a NavigatedActor -> owned by USDGNavDriverSubsystem; pawn skips it.你让 Pawn 飞了一个“已指定 Actor”的体积(互斥)→ 要么清空该体积的 Navigated Actor,要么换一个未指定体积。
指定的 Actor 不动NavigatedActor '...' unresolved; skipped (no pawn fallback).引用的 Actor 被删了 / 在未加载的子关卡里 → 重新指定一个当前关卡里存在的 Actor。
Actor 不动但无报错(无)目标 Actor 真的无法位移(没有可变换的根组件)→ 换一个有 SceneComponent 根、可移动的 Actor。
速度像被锁死 / 跟填的不一样(无)通用组件流里 bUseProjectDefaults=true 会在 BeginPlay 用项目设置覆盖 Details 里的 MoveSpeed → 设 bUseProjectDefaults=false 保留你填的值。

行为须知(别被吓到)​

  • 瞬移到起点:第一帧 Actor / Pawn 会从你摆放的位置跳到“路径起点”,再开始沿线飞——这是正常的,不是 bug。
  • 默认不循环:bLoopAllPaths = false,飞到终点就停。要来回循环就把它设为 true。

下一步​

  • 全局 JSON 配置、标签约定、控制台命令:见配置与标签。
  • 沿飞行路径采集合成数据:配合 IADataSDG。