Files
zeling_v2/Docs/ThirdPart/PathBerserker2d_Technical_Evaluation.md
2026-05-19 23:20:44 +08:00

34 KiB
Raw Blame History

PathBerserker2d 技术评估与使用手册

版本: PathBerserker2d (Unity Asset Store)
Unity 要求: 2020.3+
依赖: com.unity.modules.physics2d
许可: Unity Asset Store EULA
包路径: Assets/PathBerserker2d/
官方文档: https://oribow.github.io/PathBerserker2dDemo/Documentation/


目录

  1. 概述与设计哲学
  2. 架构总览
  3. 核心组件
  4. NavAgent 详解
  5. NavSurface 详解
  6. NavLink 与 NavLinkCluster
  7. 辅助组件
  8. 全局系统 — PBWorld 与 Settings
  9. 路径与寻路请求
  10. 预置行为脚本
  11. TransformBasedMovement 移动系统
  12. Demo 场景与使用模式
  13. Corgi 引擎集成
  14. 全局设置参考
  15. 与 BaseGames 架构集成方案
  16. 性能分析与优化建议
  17. 优缺点总结
  18. 总结与建议

1. 概述与设计哲学

1.1 什么是 PathBerserker2d

PathBerserker2d 是一款专为 2D 游戏 设计的导航/寻路插件。与 Unity 内置的 NavMesh面向 3D不同它基于 线段Segment 而非面片构建导航图,天然适合 2D 横版游戏的地形表示。

核心理念:

从 2D Collider 自动烘焙导航线段,通过多线程 A* 异步寻路,以事件驱动的方式委托移动实现。

1.2 核心设计原则

原则 说明
线段导航 导航数据为沿 Collider2D 表面的线段,适合平台跳跃和横版场景
自动烘焙 从子对象的 Collider2D 自动提取导航线段,无需手动标记
异步多线程 寻路计算在后台线程完成默认4线程不阻塞主线程
事件驱动 NavAgent 通过事件通知移动组件,移动实现完全解耦
动态世界 支持运行时烘焙、移动平台、动态链接启停
链接系统 跳跃、下落、攀爬、电梯、传送等复杂行为通过 NavLink 建模

1.3 适用场景

  • 2D 横版平台跳跃Metroidvania / Platformer
  • 2D 俯视角 RPG360° 模式)
  • 需要 AI 自动寻路的 2D 游戏
  • 含电梯、梯子、传送门、移动平台等复杂地形的关卡

2. 架构总览

2.1 系统架构图

NavSurface (烘焙 Collider2D → 线段数据)
    ↓ OnEnable 时添加
PBWorld.NavGraph (全局导航图B2DynamicTree 空间索引)
    ↑ NavLink / NavLinkCluster 添加连接
    ↑ NavAreaMarker 标记区域 NavTag
    ↑ NavSegmentSubstractor 裁剪线段

NavAgent.PathTo() → PBWorld.PathTo(PathRequest)
    ↓ 入队
PathfinderThread (多线程 A*) → PathRequest.Fulfill(Path)
    ↓ 主线程轮询
NavAgent.HandlePathRequest() → 开始 FollowPath
    ↓ 事件驱动
TransformBasedMovement / 自定义移动 (实际移动)
    ↓ 完成后回调
NavAgent.CompleteSegmentTraversal() / CompleteLinkTraversal()

2.2 关键设计模式

模式 说明
异步多线程寻路 PathRequest 入队 → PathfinderThread 后台 A* → 主线程轮询结果
事件驱动移动 NavAgent 触发事件,外部组件响应事件实现移动逻辑
动态世界 NavSurface 可运行时烘焙/加载/卸载,链接可动态添加/移除/切换可穿越性
移动平台支持 所有坐标相对 NavSurface 本地坐标存储Transform 变化时自动跟随
自动重新寻路 autoRepathIntervall 控制周期性重算路径,应对世界变化
WebGL 兼容 检测平台后使用协程替代线程,确保单线程环境可用

2.3 目录结构

Assets/PathBerserker2d/
├── Scripts/PathBerserker2d/          # 核心源码
│   ├── NavAgent/                     # NavAgent.cs, TransformBasedMovement.cs
│   │   └── NavAgentUsers/            # 预置行为脚本 (8个)
│   ├── NavSurface/                   # NavSurface.cs, 碰撞体过滤, 线段创建
│   │   ├── NavSegments/              # 线段数据结构
│   │   └── Creation/                 # 烘焙管线
│   ├── NavObjects/                   # NavLink, NavLinkCluster, NavAreaMarker 等
│   ├── NavGraph/                     # 导航图, 图节点, 空间索引
│   ├── Pathfinder/                   # A* 寻路, 路径请求, 多线程
│   ├── PBWorld.cs                    # 全局单例管理器
│   ├── PathBerserker2dSettings.cs    # 全局设置
│   └── IVelocityProvider.cs          # 速度接口
├── Demo/                             # 演示场景与脚本
│   ├── Scenes/                       # 15+ 场景
│   └── Scripts/                      # 演示脚本
├── Corgi/                            # Corgi Engine 集成层
├── Resources/                        # 全局设置资源文件
└── Documentation/                    # 官方文档 (zip)

3. 核心组件

3.1 组件总览

组件 菜单路径 职责
NavSurface PathBerserker2d/Nav Surface 从 Collider2D 烘焙导航线段
NavAgent PathBerserker2d/Nav Agent 寻路请求与路径跟随
NavLink PathBerserker2d/Nav Link 两点间导航链接(跳跃/下落/攀爬等)
NavLinkCluster PathBerserker2d/Nav Link Cluster 多点互联链接集群(电梯/梯子)
NavAreaMarker PathBerserker2d/Nav Area Marker 区域 NavTag 标记
NavSegmentSubstractor 在烘焙时裁剪指定区域的线段
DynamicObstacle 标记 GameObject 在烘焙时被忽略
TransformBasedMovement 基于 Transform 的默认移动实现

3.2 组件依赖关系

NavAgent ←需要→ TransformBasedMovement (或自定义移动组件)
NavAgent ←依赖→ PBWorld (全局单例,自动创建)
NavSurface ←依赖→ 子对象的 Collider2D
NavLink / NavLinkCluster ←映射→ NavSurface 上的线段
NavAreaMarker ←需要→ RectTransform
NavSegmentSubstractor ←需要→ RectTransform

4. NavAgent 详解

4.1 状态机

NavAgent 状态:
┌─────────┐
│  Idle    │ ←── 初始 / Stop() / ForceStop() / 到达目标
└────┬─────┘
     │ PathTo()
     ▼
┌─────────────────────────────┐
│      FollowPath             │
│  ┌─────────────────────┐    │
│  │  OnSegment           │ ←─ 在线段上移动
│  ├─────────────────────┤    │
│  │  WaitForLinkOnSegment│ ←─ 等待链接可用
│  ├─────────────────────┤    │
│  │  OnLink              │ ←─ 正在穿越链接
│  └─────────────────────┘    │
└─────────────────────────────┘

4.2 公共方法

方法 返回值 说明
PathTo(Vector2 goal) bool 寻路到目标位置
PathTo(params Vector2[] goals) bool 寻路到多个目标中最近的
UpdatePath() void 触发重新寻路(不改变目标)
SetRandomDestination() bool 设置随机目标
Stop() void 优雅停止(完成当前链接后停止)
ForceStop() void 立即强制停止
CompleteSegmentTraversal() void 通知已完成线段移动(由移动组件调用)
CompleteLinkTraversal() void 通知已完成链接穿越(由移动组件调用)
WarpToNearestSegment() void 传送到最近线段
CanTraverseLink(int linkType) bool 检查是否可穿越指定类型链接
CanReach(Vector2 goal) bool 同步检查目标是否可达
CreatePathRequest() PathRequest 创建自定义寻路请求

4.3 公共属性

属性 类型 说明
CurrentStatus NavAgentStatus 当前状态枚举
IsIdle bool 是否空闲
IsFollowingAPath bool 是否正在跟随路径
IsOnLink bool 是否正在链接上
IsMovingOnSegment bool 是否在线段上移动
HasValidPosition bool 当前位置是否有效(在线段上)
Height float 代理高度
MaxSlopeAngle float 最大坡度角
CurrentSegmentNormal Vector2 当前线段法线
PathGoal Vector2 当前路径目标
Position Vector2 代理位置
CurrentNavTagVector int 当前位置的 NavTag
TimeOnLink float 在当前链接上经过的时间

4.4 事件

事件 参数 触发时机
OnStartLinkTraversal NavAgent, PathSegment 开始穿越链接
OnLinkTraversal NavAgent, PathSegment, float t 链接穿越每帧回调t: 0→1
OnStartSegmentTraversal NavAgent, PathSegment 开始线段移动
OnSegmentTraversal NavAgent, PathSegment, float t 线段移动每帧回调
OnFailedToFindPath 寻路失败
OnStop 停止移动
OnReachedGoal 到达目标
OnStartFollowingNewPath 开始跟随新路径

4.5 Inspector 配置

字段 默认值 说明
height 1 代理高度(影响净空检查)
maxSlopeAngle 60 最大可行走坡度角
autoRepathIntervall 1 自动重新寻路间隔(秒)
maximumDistanceToPathStart 到路径起点的最大距离
linkTraversalCostMultipliers[] 各链接类型代价乘数
navTagTraversalCostMultipliers[] 各 NavTag 代价乘数
allowCloseEnoughPath false 允许"近似到达"路径
enableDebugMessages false 启用调试日志

5. NavSurface 详解

5.1 核心概念

NavSurface 是导航数据的来源。它扫描子对象上的 Collider2D,沿碰撞体表面生成导航线段,并在烘焙完成后将数据添加到全局 NavGraph。

关键特性:

  • 自动烘焙:编辑器中或运行时均可烘焙
  • 移动平台烘焙数据以本地坐标存储NavSurface Transform 移动时路径跟随
  • 动态加载OnEnable 添加到 NavGraphOnDisable 移除

5.2 公共属性

属性 类型 说明
WorldBounds Rect 世界空间包围盒
MaxClearance float 最大净空检查高度
MinClearance float 最小净空(低于此值的线段被移除)
CellSize float 净空检查精度
ColliderMask LayerMask 碰撞体过滤层
TotalLineLength float 所有线段总长度
MaxSlopeAngle float 最大坡度角
LocalToWorldMatrix Matrix4x4 本地到世界矩阵

5.3 公共方法

方法 说明
IEnumerator Bake() 运行时烘焙(协程)
Vector2 LocalToWorld(Vector2 pos) 本地坐标转世界坐标
Vector2 WorldToLocal(Vector2 pos) 世界坐标转本地坐标

5.4 事件

事件 说明
OnBakingCompleted 烘焙完成
OnReadyToPathfind 已添加到 NavGraph可以开始寻路
OnRemovedFromPathfinding 已从 NavGraph 移除

5.5 Inspector 烘焙配置

字段 默认值 说明
maxClearance 1.8 障碍检查最大高度
minClearance 0.1 净空低于此值的线段被移除
cellSize 0.1 障碍检查精度(越小越精确但越慢)
includedColliders ~0 参与烘焙的层
onlyStaticColliders false 仅包含静态碰撞体
maxSlopeAngle 180 移除超过此角度的线段
smallestDistanceYouCareAbout 0.1 RDP 线简化容差
minSegmentLength 0.1 最小线段长度

5.6 使用示例

场景层级结构:
NavSurface (GameObject)
├── Ground (BoxCollider2D)
├── Platform_1 (BoxCollider2D)
├── Platform_2 (PolygonCollider2D)
└── Wall (BoxCollider2D)

注意: NavSurface 只扫描 子对象 上的 Collider2D自身上的碰撞体不会被烘焙。


NavLink 连接两个点,代表跳跃、下落、攀爬等需要特殊处理的路径段。

可视化类型

类型 说明
Linear 直线
QuadradticBezier 二次贝塞尔曲线
Projectile 抛物线
Teleport 传送(瞬移)
None 无可视化
TransformBasedMovement 使用 TransformBasedMovement 的默认处理

公共属性

属性 类型 说明
GoalWorldPosition Vector2 目标世界位置(可读写)
StartWorldPosition Vector2 起点世界位置(可读写)
IsBidirectional bool 是否双向
IsAddedToWorld bool 是否已添加到 NavGraph

公共方法

方法 说明
UpdateMapping() 位置改变后更新链接映射
SetStartToGoalLinkTraversable(bool) 设置正向可穿越性
SetGoalToStartLinkTraversable(bool) 设置反向可穿越性
属性 说明
LinkType 链接类型索引corner=0, jump=1, fall=2, teleport=3, climb=4, elevator=5
Clearance 允许通过的最大代理高度
AvgWaitTime 平均等待时间(影响寻路代价)
CostOverride 代价覆盖≤0 使用距离计算)
NavTag NavTag 标记
MaxTraversableDistance 最大可穿越距离
autoMap 自动映射到 NavGraph

6.2 NavLinkCluster — 链接集群

NavLinkCluster 适用于多点互联场景,如 电梯(多层站点)、梯子(多个停靠点)。

内部为每对点自动生成一个链接。

LinkPoint 结构

struct LinkPoint {
    Vector2 point;
    PointTraversalType traversalType;  // Exit | Entry | Both
}

公共方法

方法 说明
UpdateMapping() 更新所有链接映射
SetLinksTraversable(Func<Vector2, Vector2, bool>) 根据起终点函数设置各链接可穿越性

使用场景

// 电梯到达某层时,只允许穿越与该层相关的链接
navLinkCluster.SetLinksTraversable((start, goal) =>
    Mathf.Abs(start.y - currentFloor.position.y) < 0.1f ||
    Mathf.Abs(goal.y - currentFloor.position.y) < 0.1f);

// 离开时禁用所有链接
navLinkCluster.SetLinksTraversable((start, goal) => false);

7. 辅助组件

7.1 NavAreaMarker — 区域标记

要求: RectTransform

将矩形区域内的所有导航线段标记为指定 NavTag。常用于标记水域、危险区域、门区域等。

属性/方法 说明
NavTag NavTag 索引
MarkerColor 标记颜色
updateAfterTimeOfNoMovement 停止移动后更新延迟
updateAfterTime 最大更新间隔
UpdateMappings() 手动更新映射

门控模式: 通过启用/禁用 NavAreaMarker 来控制门的通行:

// 开门 → 禁用标记 → 代理可通过
navAreaMarker.enabled = false;
// 关门 → 启用标记 → 区域被标记为不可通行 NavTag
navAreaMarker.enabled = true;

7.2 NavSegmentSubstractor — 线段裁剪器

要求: RectTransform

在烘焙时从指定矩形区域移除线段。支持角度过滤:

字段 说明
fromAngle 最小角度过滤
toAngle 最大角度过滤

7.3 DynamicObstacle — 动态障碍物

空标记组件。附加到 GameObject 上,使其在 NavSurface 烘焙时被忽略。

7.4 IVelocityProvider — 速度接口

interface IVelocityProvider {
    Vector2 WorldVelocity { get; }
}

用于 Follower 组件的目标预测功能。在跟随目标上实现此接口即可。


8. 全局系统 — PBWorld 与 Settings

8.1 PBWorld — 全局单例

自动实例化,DontDestroyOnLoad。管理全局 NavGraph 和寻路调度。

静态 API

// === 点映射 ===
// 映射世界点到最近导航位置
static bool TryMapPoint(Vector2 position, out NavSegmentPositionPointer pointer)
// 自定义搜索半径
static bool TryMapPoint(Vector2 position, float searchRadius, out NavSegmentPositionPointer pointer)
// 确保映射位置对代理可通行
static bool TryMapPoint(Vector2 position, float searchRadius, NavAgent agent, out NavSegmentPositionPointer pointer)

// === 随机 ===
static Vector2 GetRandomPointOnGraph()  // 返回图上随机点

// === 寻路 ===
static void PathTo(PathRequest pathRequest)  // 入队异步寻路请求

// === 空间查询 ===
static List<NavSubsegmentPointer> BoxCast(Rect rect, float rotation, float fromAngle, float toAngle)

// === 图变化监听 ===
static INavGraphChangeSource NavGraphChangeSource  // 订阅 OnGraphChange 事件

NavGraphChange 事件枚举

说明
NavSurfaceAdded NavSurface 添加
NavSurfaceRemoved NavSurface 移除
NavLinkAdded NavLink 添加
NavLinkRemoved NavLink 移除
SegmentModifierAdded 线段修改器添加
SegmentModifierRemoved 线段修改器移除
NavLinkMoved NavLink 位置变更

8.2 NavSegmentPositionPointer

导航位置指针结构体,用于表示一个在导航图上的有效位置:

属性 类型 说明
Position Vector2 世界位置
Normal Vector2 法线
IsValid() bool 是否有效
IsInvalid() bool 是否无效

9. 路径与寻路请求

9.1 PathRequest — 寻路请求

枚举
RequestState Draft, Pending, Finished, Failed
RequestFailReason CouldntMapStart, CouldntMapGoal, MappedStartChanged, AllMappedGoalsChanged, NoPathFromStartToGoal, WorldWasDestroyed, ToFarFromStart
属性 类型 说明
Status RequestState 请求状态
FailReason RequestFailReason 失败原因
Path Path 计算出的路径
start NavSegmentPositionPointer 起点
goals IList<NavSegmentPositionPointer> 目标列表
client NavAgent 请求代理

9.2 Path — 路径

属性/方法 说明
Current 当前路径片段 (PathSegment)
NextSegment 下一个片段
HasNext 是否有下一个
Goal 目标位置
Start 起点位置
totalCosts 总代价
MoveNext() 前进到下一片段
AllPathPoints() 获取所有路径点列表
RemainingPathPoints() 获取剩余路径点列表

9.3 PathSegment — 路径片段

属性/方法 说明
Next 下一个片段
LinkStart 链接起点(世界坐标,随 NavSurface 移动)
LinkEnd 链接终点
Normal 线段法线
Tangent 线段切线
Point 线段上的参考点
link 关联的链接实例
owner 所属 NavSurface
GetTagVector(float t) 获取位置的 NavTag
DistanceAlongSegment(Vector2 pos) 投影距离

10. 预置行为脚本

PathBerserker2d 提供 8 个即用的 NavAgent 行为脚本:

组件 说明 典型用途
MouseWalker 鼠标点击处寻路 调试、点击移动原型
PatrolWalker 按顺序巡逻路线,循环 巡逻敌人
RandomWalker 持续随机行走 NPC 闲逛
MultiGoalWalker 寻路到多个目标中最近的一个 收集物搜索
Follower 跟随目标 Transform支持目标预测 追踪型敌人
KeepGrounded 通过 Raycast 检测移动平台并 parent 移动平台上的代理
AdjustRotation 旋转代理匹配线段法线方向 沿曲面行走的方向适配
FootStepSounds 根据 NavTag 播放不同脚步声 环境音效

使用方式

直接将这些脚本添加到带有 NavAgent 的 GameObject 上即可。它们自动获取同 GameObject 上的 NavAgent 引用。


11. TransformBasedMovement 移动系统

11.1 概述

TransformBasedMovement 是 PathBerserker2d 提供的默认移动实现。它订阅 NavAgent 的事件,在回调中直接修改 Transform 位置,并在完成后调用 CompleteSegmentTraversal() / CompleteLinkTraversal() 通知 NavAgent。

11.2 FeatureFlags

[Flags] enum FeatureFlags {
    SegmentMovement = 1,    // 线段移动
    JumpLinks       = 2,    // 跳跃链接
    CornerLinks     = 4,    // 拐角链接
    FallLinks       = 8,    // 下落链接
    TeleportLinks   = 16,   // 传送链接
    ClimbLinks      = 32,   // 攀爬链接
    ElevatorLinks   = 64,   // 电梯链接
    OtherLinks      = 128,  // 其他链接
}

11.3 配置属性

字段 默认值 说明
movementSpeed 5 线段移动速度 (unit/s)
cornerSpeed 100 拐角链接速度 (degrees/s)
jumpSpeed 5 跳跃速度 (unit/s)
fallSpeed 5 下落速度 (unit/s)
climbSpeed 5 攀爬速度 (unit/s)
enableAgentRotation true 是否旋转代理朝向移动方向
enabledFeatures 全部启用 控制由本组件处理的功能

11.4 自定义移动组件

如果 TransformBasedMovement 不满足需求(例如需要物理驱动移动),可以创建自定义移动组件:

public class CustomMovement : MonoBehaviour
{
    NavAgent navAgent;
    
    void Awake() => navAgent = GetComponent<NavAgent>();
    
    void OnEnable()
    {
        navAgent.OnStartSegmentTraversal += HandleSegmentStart;
        navAgent.OnSegmentTraversal += HandleSegmentMove;
        navAgent.OnStartLinkTraversal += HandleLinkStart;
        navAgent.OnLinkTraversal += HandleLinkMove;
    }
    
    void HandleSegmentMove(NavAgent agent, PathSegment seg, float t)
    {
        // 自定义线段移动逻辑
        // ...
        // 完成后:
        agent.CompleteSegmentTraversal();
    }
    
    void HandleLinkMove(NavAgent agent, PathSegment seg, float t)
    {
        // 自定义链接穿越逻辑
        // ...
        // 完成后:
        agent.CompleteLinkTraversal();
    }
}

12. Demo 场景与使用模式

12.1 Demo 场景一览

场景 展示内容
breakable_wall 可破坏墙壁 + 寻路
door NavAreaMarker 门控
elevator NavLinkCluster 电梯系统
follow_target Follower 跟随行为
ladder 攀爬链接
moving_platform 移动平台导航
multi_surface 多 NavSurface 场景
procedural_endless_jumper 运行时烘焙
runtime_bake 运行时动态烘焙
simple_patrol 基础巡逻
teleport 传送链接
threesixtydegree 360° 全向导航
trafficlight 交通灯 + 等待逻辑
tricky_jump 复杂跳跃场景

12.2 常用使用模式

模式 1最简单的寻路

// GoalWalker 模式:检查距离 + IsIdle → PathTo
void Update()
{
    if (Vector2.Distance(goal.position, navAgent.transform.position) > 0.5f
        && (navAgent.IsIdle || goal.hasChanged))
    {
        goal.hasChanged = false;
        navAgent.PathTo(goal.position);
    }
}

模式 2电梯 — 动态链接切换

// 电梯到达某层 → 启用相关链接
navLinkCluster.SetLinksTraversable((start, goal) =>
    Mathf.Abs(start.y - levels[nextLevel].position.y) < 0.1f ||
    Mathf.Abs(goal.y - levels[nextLevel].position.y) < 0.1f);

// 电梯离开 → 禁用所有链接
navLinkCluster.SetLinksTraversable((start, goal) => false);

模式 3门 — NavAreaMarker 控制

// 开门:禁用 NavAreaMarker → 区域不再有阻挡标记
navAreaMarker.enabled = false;

// 关门:启用 NavAreaMarker → 门区域被标记为不可通行 NavTag
navAreaMarker.enabled = true;

模式 4移动平台

// MovingPlatform 是 NavSurface 的子对象
// 只需移动 NavSurface 的 Transform导航数据自动跟随
transform.Translate(velocity * Time.deltaTime);

模式 5运行时烘焙

// 在运行时触发烘焙
StartCoroutine(navSurface.Bake());

// 监听烘焙完成
navSurface.OnBakingCompleted += () => Debug.Log("Bake done!");
navSurface.OnReadyToPathfind += () => Debug.Log("Ready for pathfinding!");

13. Corgi 引擎集成

PathBerserker2d 附带 CorgiBasedMovement 组件,替代 TransformBasedMovement 以对接 Corgi Engine 的角色控制系统。

13.1 核心映射

导航行为 Corgi 映射
线段移动 CharacterHorizontalMovement.SetHorizontalMove()
跳跃链接 CharacterJump.JumpStart()
攀爬链接 CharacterLadder(反射调用)
传送链接 直接设置 Position
拐角链接 直接 CompleteLinkTraversal()
卡住检测 fallbackTeleportDelay 秒后传送

13.2 Corgi AI Actions

脚本 说明
AIActionPBMoveTowardsTarget 移向目标
AIActionPBMoveTowardsClosestTarget 移向最近目标
AIActionPBMoveTowardsRandomPathableTarget 移向可达随机目标
AIActionPBPatrol 巡逻
AIDecisionPBHasReachedGoal 判断是否到达
AIDecisionPBPathfindingFailed 判断寻路失败

注意: 本项目使用自研架构而非 Corgi Engine此集成仅作参考。


14. 全局设置参考

位置: Edit > Project Settings > PathBerserker2d
资源文件: Assets/PathBerserker2d/Resources/PathBerserker2dSettings

14.1 设置项

属性 类型 当前值 说明
PointMappingDistance float 0.2 点映射最大距离(性能关键,应尽量小)
PathfinderThreadCount int 4 寻路线程数WebGL 强制 = 1
InitiateUpdateInterval float 0.1s NavGraph 更新间隔
DrawGraphWhilePlaying bool 运行时绘制导航图
NavSurfaceLineWidth float 线宽
UsePolygonCollider2dPathsForBaking bool 多边形碰撞体烘焙方式

14.2 内置链接类型

索引 名称 说明
0 corner 拐角(自动生成)
1 jump 跳跃
2 fall 下落
3 teleport 传送
4 climb 攀爬
5 elevator 电梯

14.3 内置 NavTag

名称 用途
default 默认
water 水域
lava 岩浆
grass 草地
concrete 混凝土
dirt 泥土

15. 与 BaseGames 架构集成方案

15.1 防腐层原则

根据 BaseGames 架构总纲(00_Architecture_Overview.md)第 3 条设计理念:

防腐层隔离: 业务代码永远不直接调用 PathBerserker2d 等第三方 API。所有第三方交互通过 Adapters/ 层代理。

因此 PathBerserker2d 的所有功能必须通过 适配器层 暴露给业务系统。

15.2 适配器设计

Layer 3 — Adapters/
└── NavAgentAdapter.cs          # PathBerserker2d NavAgent 的防腐包装

业务层调用链:
EnemyAI (Layer 5) → NavAgentAdapter (Layer 3) → NavAgent (第三方)

NavAgentAdapter 接口建议

namespace BaseGames.Adapters
{
    /// <summary>
    /// PathBerserker2d NavAgent 的防腐层适配器。
    /// 业务代码通过此接口进行寻路,不直接引用 PathBerserker2d API。
    /// </summary>
    public interface INavigation
    {
        bool PathTo(Vector2 goal);
        bool PathTo(params Vector2[] goals);
        void Stop();
        void ForceStop();
        bool IsIdle { get; }
        bool IsFollowingPath { get; }
        bool CanReach(Vector2 goal);
        Vector2 CurrentPosition { get; }
        
        event Action OnReachedGoal;
        event Action OnPathFailed;
        event Action OnStopped;
    }
}

15.3 与其他系统的集成点

BaseGames 系统 集成方式
敌人 AI (20_Enemy_AI) 行为树通过 INavigation 接口调用寻路
环境系统 (11_Environment) MovingPlatform 使用 NavSurface 子对象模式
环境系统 (11_Environment) BreakableWall 销毁后触发 NavSurface 重新烘焙
环境系统 (11_Environment) TeleportGate 对应 NavLinkteleport 类型)
物理动画 (08_Physics) 自定义移动组件桥接 IPhysicsBody 与 NavAgent 事件
标签系统 (02_GameTag) NavTag 可映射为 GameTagSO 用于环境效果触发

15.4 自定义移动组件集成

由于 BaseGames 使用自研物理系统 (IPhysicsBody / RaycastBody2D),不应使用默认的 TransformBasedMovement。需要创建桥接移动组件:

namespace BaseGames.Adapters
{
    public class PhysicsBasedNavMovement : MonoBehaviour
    {
        // 订阅 NavAgent 事件
        // 将移动指令转发给 IPhysicsBody
        // 通过 IPhysicsBody 驱动实际移动
        // 移动完成后调用 CompleteSegmentTraversal() / CompleteLinkTraversal()
    }
}

16. 性能分析与优化建议

16.1 性能特性

方面 评估
寻路 多线程 A*,不阻塞主线程。线程数可配置(默认 4
烘焙 协程方式,可分帧执行。复杂场景烘焙较重
内存 线段数据以本地坐标存储,紧凑
空间索引 B2DynamicTreeBox2D 动态树),查询高效
WebGL 自动降级为单线程协程模式

16.2 优化建议

建议 说明
减小 PointMappingDistance 当前 0.2,越小映射查询越快
调整 autoRepathIntervall 不要过于频繁1-2 秒通常足够
合理设置 cellSize 烘焙精度越高越慢0.1 适合大多数情况
分区管理 NavSurface 按房间/区域拆分 NavSurface按需启用/禁用
限制同时寻路数 大量代理时排队处理,避免请求洪峰
善用 onlyStaticColliders 排除动态碰撞体可加速烘焙

17. 优缺点总结

17.1 优势

优势 说明
原生 2D 支持 基于线段而非面片,天然适合 2D 横版游戏
完整源码 所有代码可见,便于调试和定制
链接系统丰富 内置 6 种链接类型,覆盖跳跃/下落/攀爬/电梯/传送/拐角
动态世界 运行时烘焙、移动平台、动态链接切换
多线程寻路 不阻塞主线程,支持多代理并发
事件驱动架构 移动实现完全解耦,易于替换为自定义移动系统
预置行为丰富 8 个即用行为脚本覆盖常见场景
移动平台支持 本地坐标体系自动跟随 NavSurface Transform 变化

17.2 不足

不足 说明
文档较简陋 官方文档以 Demo 为主,缺少系统性 API 文档
无官方维护迹象 Asset Store 版本更新不频繁
烘焙仅支持 Collider2D 不支持 Tilemap 直接烘焙(需转换为 Collider
链接需手动放置 跳跃/攀爬等链接需要手动在编辑器中放置
360° 模式限制 虽支持 360° 但主要为横版优化
缺少动态避障 无 RVO / ORCA 等动态避障实现
NavTag 数量有限 内置 6 个 NavTag扩展需修改设置

17.3 技术评分

维度 评分 (1-10) 说明
2D 适配度 9 专为 2D 设计,线段导航非常贴合横版场景
API 设计 8 事件驱动架构清晰,易于扩展
文档质量 5 Demo 丰富但系统文档不足
性能 8 多线程寻路 + B2DynamicTree 空间索引
易用性 7 基础使用简单,高级功能学习曲线稍陡
可维护性 7 完整源码可见,但注释较少
扩展性 8 事件驱动 + 接口隔离,易接入自定义系统
综合 7.4 适合 2D Metroidvania 项目的可靠寻路方案

18. 总结与建议

18.1 总体评价

PathBerserker2d 是目前 Unity 生态中少有的 专为 2D 横版设计 的寻路方案。其基于线段的导航模型天然适配平台跳跃类游戏,多线程异步寻路保证了性能,事件驱动架构提供了良好的扩展性。

对于 BaseGames 这样的 2D Metroidvania 项目,它提供了:

  • 完整的 2D 导航能力:地面行走、跳跃、下落、攀爬、电梯、传送
  • 移动平台支持:天然适配关卡中的动态地形
  • 与自定义物理系统的解耦:通过事件驱动架构可桥接 IPhysicsBody

18.2 集成建议

  1. 严格通过适配器层访问 — 遵循 BaseGames 防腐层原则,创建 NavAgentAdapter / INavigation 接口
  2. 替换 TransformBasedMovement — 创建 PhysicsBasedNavMovement 桥接 IPhysicsBody
  3. 按房间分区 NavSurface — 配合关卡加载系统,按需启用/禁用导航区域
  4. NavTag 映射 GameTagSO — 统一标签体系,复用效果系统触发逻辑
  5. 行为树集成 — 通过 INavigation 接口在行为树节点中调用寻路

18.3 注意事项

  • 可破坏墙壁销毁后需触发 NavSurface 重新烘焙
  • 电梯/升降台需使用 NavLinkCluster 配合动态可穿越性控制
  • 大量 AI 代理场景需排队管理寻路请求避免性能瓶颈
  • WebGL 构建时自动降级为单线程,需额外测试性能