Unity_导航网格
Unity导航网格系统为AI角色提供自动寻路能力,包含四个核心模块:Agents(配置代理属性)、Areas(定义导航区域)、Bake(生成导航网格)和Object(设置场景对象)。其工作流程包括配置代理参数、设置区域类型、标记场景对象并烘焙生成导航网格。系统提供NavMeshAgent组件实现寻路功能,支持速度、避障、路径规划等参数设置。注意事项包括合理设置Voxel Size平衡性能与精度,正
·
Unity导航网格
1. 导航网格工具概述
1.1 基本概念
- 导航网格(Navigation Mesh):Unity内置的AI寻路系统
- 作用:为游戏中的AI角色提供自动寻路能力
- 特点:可视化编辑、实时预览、性能优化
1.2 四个核心模块
1.2.1 Agents(代理页签)
- 作用:用于配置寻路代理信息
- 功能:定义AI角色的物理属性和移动参数
- 主要设置:
- Agent Types:代理类型(如Humanoid)
- Name:代理名称
- Radius:代理半径(影响寻路精度)
- Height:代理高度(决定可通过的通道高度)
- Step Height:可跨越的台阶高度
- Max Slope:可攀爬的最大坡度
1.2.2 Areas(导航地区页签)
- 作用:配合Object页签使用,定义导航区域类型
- 功能:设置不同区域的寻路消耗和通行规则
- 主要设置:
- Name:区域名字,用于标识不同类型的导航区域
- Cost:寻路消耗,数值越高AI越不愿意走该区域
- 应用场景:区分道路、草地、水域等不同地形类型
1.2.3 Bake(导航数据烘焙页签)
- 作用:生成导航网格数据
- 功能:根据场景几何体和代理设置计算可行走区域
- 核心参数:
- Agent Properties:代理属性设置
- Agent Radius:代理半径(0.5)
- Agent Height:代理高度(2)
- Max Slope:最大坡度(45°)
- Step Height:最小楼梯高度(0.4)
- Generated Off Mesh Links:生成非网格连接
- Drop Height:掉落高度(0)
- Jump Distance:跳跃距离(0)
- Advanced Settings:高级设置
- Voxel Size:立体像素大小(影响精度和性能)
- Min Region Area:最小区域面积(2)
- Height Mesh:高度网格构建开关
- Agent Properties:代理属性设置
1.2.4 Object(场景对象设置页签)
- 作用:配置场景中具体对象的导航属性
- 功能:设置哪些对象参与导航网格生成
- 主要设置:
- Scene Filter:场景过滤器,配合Hierarchy窗口使用
- All:显示场景上所有对象
- Mesh Renderers:显示挂载网格渲染器的对象
- Terrains:显示挂载地形脚本的对象
- Navigation Static:导航静态物体开关
- Generate OffMeshLinks:生成网格连接点开关
- Navigation Area:导航区域选择,配合Areas页签使用
- Scene Filter:场景过滤器,配合Hierarchy窗口使用
1.3 工作流程
┌─────────────────────────────────────────────────────────────┐
│ Unity导航网格工作流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 配置代理 │───▶│ 设置区域 │───▶│ 对象配置 │ │
│ │ Agents │ │ Areas │ │ Object │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 烘焙生成 │◀───│ 预览检查 │◀───│ 应用寻路 │ │
│ │ Bake │ │ Scene View │ │ NavMesh │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
1.4 使用注意事项
- 性能考虑:Voxel Size越小精度越高,但内存占用和烘焙时间会显著增加
- 区域设置:合理设置Navigation Area和Cost值,避免AI选择不合理的路径
- 对象标记:确保需要参与导航的对象都正确标记为Navigation Static
- 烘焙优化:大型场景建议分区域烘焙,提高工作效率
2. 导航网格组件
2.1 组件架构概述
- 核心组件:构成Unity导航系统的功能模块
- 作用:为AI角色提供寻路、避障、路径规划等能力
- 特点:模块化设计、易于配置、性能优化
2.2 主要组件类型
2.2.1 NavMeshAgent(导航网格代理)
- 作用:AI角色的核心寻路组件
- 功能:自动寻路、避障、路径规划
- 主要属性:
- Agent Type:代理类型设置
- Speed:移动速度
- Angular Speed:旋转速度
- Acceleration:加速度
- Stopping Distance:停止距离
- Radius:代理半径
- Height:代理高度
2.2.1.1 基础代码示例
using UnityEngine;
using UnityEngine.AI;
public class NavMeshAgentDemo : MonoBehaviour
{
private NavMeshAgent agent;
public Transform target; // 目标位置
void Start()
{
// 获取或添加NavMeshAgent组件
agent = GetComponent<NavMeshAgent>();
if (agent == null)
{
agent = gameObject.AddComponent<NavMeshAgent>();
}
// 基础属性设置
agent.speed = 5f; // 移动速度
agent.angularSpeed = 120f; // 旋转速度
agent.acceleration = 8f; // 加速度
agent.stoppingDistance = 1f; // 停止距离
agent.radius = 0.5f; // 代理半径
agent.height = 2f; // 代理高度
}
void Update()
{
// 设置目标位置
if (target != null)
{
agent.SetDestination(target.position);
}
}
}
2.2.1.2 高级功能代码示例
using UnityEngine;
using UnityEngine.AI;
public class AdvancedNavMeshAgent : MonoBehaviour
{
private NavMeshAgent agent;
public Transform[] waypoints; // 路径点数组
private int currentWaypoint = 0;
void Start()
{
agent = GetComponent<NavMeshAgent>();
SetupAgent();
}
void SetupAgent()
{
// 高级属性设置
agent.avoidancePriority = 50; // 避障优先级
agent.autoTraverseOffMeshLink = true; // 自动通过OffMeshLink
agent.autoRepath = true; // 自动重新寻路
agent.pathfindingIterationsPerFrame = 100; // 每帧寻路迭代次数
}
void Update()
{
// 巡逻逻辑
if (waypoints.Length > 0)
{
if (agent.remainingDistance < 0.5f)
{
currentWaypoint = (currentWaypoint + 1) % waypoints.Length;
agent.SetDestination(waypoints[currentWaypoint].position);
}
}
}
// 手动寻路到指定位置
public void MoveTo(Vector3 destination)
{
if (agent.isOnNavMesh)
{
agent.SetDestination(destination);
}
}
// 检查是否到达目标
public bool HasReachedDestination()
{
return !agent.pathPending &&
agent.remainingDistance <= agent.stoppingDistance;
}
// 停止移动
public void StopMoving()
{
agent.isStopped = true;
}
// 恢复移动
public void ResumeMoving()
{
agent.isStopped = false;
}
}
2.2.2 NavMeshObstacle(导航网格障碍物)
- 作用:动态障碍物组件
- 功能:实时更新导航网格,创建动态障碍
- 主要属性:
- Shape:障碍物形状
- Size:障碍物尺寸
- Carving:是否雕刻导航网格
- Movement Threshold:移动阈值
2.2.2.1 动态障碍物组件的用途
- 游戏场景应用:在游戏场景中,经常有这样的功能:
- 场景中有一扇门,如果这扇门没有被破坏,AI角色无法自动寻路到门后的场景
- 只有当门被破坏后,AI角色才能通过到下一个场景
- 像门这样的对象本身不需要进行寻路,所以不需要给它们添加NavMeshAgent脚本
- 在这种情况下,使用"动态障碍物组件"(NavMeshObstacle)来实现这个功能
2.2.2.2 动态障碍物组件的使用方法
- 基本设置:为需要动态阻挡AI的对象添加NavMeshObstacle组件
- 形状配置:根据对象的实际形状设置障碍物的几何形状
- 尺寸调整:调整障碍物的尺寸以准确反映阻挡范围
- 雕刻设置:启用Carving功能,让障碍物能够实时更新导航网格
- 移动阈值:设置Movement Threshold,控制障碍物移动多少距离后才更新导航网格
2.2.2.3 代码示例
using UnityEngine;
using UnityEngine.AI;
public class DynamicObstacle : MonoBehaviour
{
private NavMeshObstacle obstacle;
void Start()
{
// 获取或添加NavMeshObstacle组件
obstacle = GetComponent<NavMeshObstacle>();
if (obstacle == null)
{
obstacle = gameObject.AddComponent<NavMeshObstacle>();
}
// 基础设置
obstacle.shape = NavMeshObstacleShape.Box; // 设置为盒子形状
obstacle.size = Vector3.one; // 设置尺寸
obstacle.carving = true; // 启用雕刻功能
obstacle.movementThreshold = 0.1f; // 移动阈值
}
// 动态启用/禁用障碍物
public void SetObstacleActive(bool active)
{
if (obstacle != null)
{
obstacle.carving = active;
}
}
// 动态调整障碍物尺寸
public void UpdateObstacleSize(Vector3 newSize)
{
if (obstacle != null)
{
obstacle.size = newSize;
}
}
// 门被破坏时的处理
public void OnDoorDestroyed()
{
// 禁用障碍物,让AI可以通过
SetObstacleActive(false);
// 或者直接销毁组件
if (obstacle != null)
{
Destroy(obstacle);
}
}
}
2.2.3 NavMeshSurface(导航网格表面)
- 作用:生成和管理导航网格表面
- 功能:动态生成、更新导航网格
- 主要属性:
- Collection Object:收集对象
- Use Geometry:使用几何体类型
- Default Area:默认区域
- Layer Mask:层级遮罩
2.2.4 NavMeshLink(导航网格连接)
- 作用:连接分离的导航网格区域
- 功能:创建跳跃、掉落等特殊移动连接
- 主要属性:
- Start Point:起始点
- End Point:结束点
- Width:连接宽度
- Cost Override:成本覆盖
2.2.4.1 详细属性说明
- Start(起始点):连接点的起始位置,指定为Transform组件
- End(结束点):连接点的结束位置,指定为Transform组件
- Cost Override(覆盖消耗值):
- 负值或0:使用所属Area的寻路消耗
- 正值:Area的寻路消耗 × 正值 = 该连接点的寻路消耗
- 用途:自定义连接点的寻路消耗,解决"步行"和"连接点"都能到达目标,但希望优先选择步行区域的情况
- Bi Directional(双向连接点):
- 启用:可以从Start到End,也可以从End到Start
- 禁用:只能从Start到End单向通行
- Activated(启用连接点):是否启用该连接点,禁用时在自动寻路中无效
- Auto Update Positions(自动更新位置):
- 启用:起始和结束位置变化时,导航网格自动更新
- 禁用:即使位置变化,仍按初始位置计算
- Navigation Area(导航区域):指定连接点所属的导航区域类型,影响哪些代理可以使用以及默认消耗
2.2.4.2 代码示例
using UnityEngine;
using UnityEngine.AI;
public class NavMeshLinkController : MonoBehaviour
{
public Transform startPoint;
public Transform endPoint;
public float costOverride = -1f;
public bool biDirectional = true;
public bool activated = true;
public bool autoUpdatePositions = false;
private OffMeshLink offMeshLink;
void Start()
{
CreateOffMeshLink();
}
void CreateOffMeshLink()
{
// 创建OffMeshLink组件
offMeshLink = gameObject.AddComponent<OffMeshLink>();
// 设置起始和结束点
offMeshLink.startTransform = startPoint;
offMeshLink.endTransform = endPoint;
// 设置连接点属性
offMeshLink.costOverride = costOverride;
offMeshLink.biDirectional = biDirectional;
offMeshLink.activated = activated;
offMeshLink.autoUpdatePositions = autoUpdatePositions;
// 设置导航区域(默认为Walkable)
offMeshLink.area = 0; // 0 = Walkable
}
// 动态启用/禁用连接点
public void SetLinkActive(bool active)
{
if (offMeshLink != null)
{
offMeshLink.activated = active;
}
}
// 动态设置成本覆盖
public void SetCostOverride(float cost)
{
if (offMeshLink != null)
{
offMeshLink.costOverride = cost;
}
}
// 检查连接点是否有效
public bool IsLinkValid()
{
return offMeshLink != null &&
offMeshLink.activated &&
offMeshLink.startTransform != null &&
offMeshLink.endTransform != null;
}
}
2.2.4.3 使用场景示例
// 跳跃连接点示例
public class JumpLink : MonoBehaviour
{
public Transform jumpStart;
public Transform jumpEnd;
public float jumpCost = 2f; // 跳跃消耗较高
void Start()
{
var link = gameObject.AddComponent<OffMeshLink>();
link.startTransform = jumpStart;
link.endTransform = jumpEnd;
link.costOverride = jumpCost;
link.biDirectional = true;
link.activated = true;
}
}
// 单向连接点示例(如滑梯)
public class SlideLink : MonoBehaviour
{
public Transform slideStart;
public Transform slideEnd;
void Start()
{
var link = gameObject.AddComponent<OffMeshLink>();
link.startTransform = slideStart;
link.endTransform = slideEnd;
link.costOverride = 0.5f; // 滑梯消耗较低
link.biDirectional = false; // 单向滑行
link.activated = true;
}
}
更多推荐

所有评论(0)