当前位置: 首页 > ds >正文

Unity_导航网格

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:高度网格构建开关
1.2.4 Object(场景对象设置页签)
  • 作用:配置场景中具体对象的导航属性
  • 功能:设置哪些对象参与导航网格生成
  • 主要设置
    • Scene Filter:场景过滤器,配合Hierarchy窗口使用
      • All:显示场景上所有对象
      • Mesh Renderers:显示挂载网格渲染器的对象
      • Terrains:显示挂载地形脚本的对象
    • Navigation Static:导航静态物体开关
    • Generate OffMeshLinks:生成网格连接点开关
    • Navigation Area:导航区域选择,配合Areas页签使用

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; // 自动通过OffMeshLinkagent.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;}
}
http://www.xdnf.cn/news/18040.html

相关文章:

  • 我的第一个音乐元素浏览项目上传至Github啦!
  • MyBatis 与 MyBatis-Plus 的区别
  • STM32L051同时处理Alarm A和Alarm B中断
  • SSH协议的GIT转换
  • 系统介绍pca主成分分析算法
  • flutter开发(二)检测媒体中的静音
  • Day59--图论--47. 参加科学大会(卡码网),94. 城市间货物运输 I(卡码网)
  • 【DDIA】第二部分:分布式数据
  • 应用层协议——HTTP
  • 抽奖程序web程序
  • JavaScript 基础实战:DOM 操作、数据类型与常见需求实现
  • 项目管理工具
  • NPM 、 NPX
  • 清除 pnpm 缓存,解决不同源安装依赖包失败的问题
  • electron之win/mac通知免打扰
  • 【R语言】R 语言中 gsub 与正则表达式详解(含 POSIX 与 Perl 风格实例)
  • 汽车电子:现代汽车的智能核心
  • [激光原理与应用-287]:理论 - 波动光学 - 电磁波既能承载能量,又能承载信息?
  • 【软件设计模式】前置知识类图、七大原则(精简笔记版)
  • Spark 运行流程核心组件(二)任务调度
  • EN/IEC 55015 照明设备的电磁兼容标准安全
  • Docker Compose部署Clickhouse最新版
  • 【LINUX网络】HTTP协议基本结构、搭建自己的HTTP简单服务器
  • 为什么游戏会出现“卡顿”:`clock.tick()` v.s. `clock.get_fps()`
  • 【uni-app】根据角色/身份切换显示不同的 自定义 tabbar
  • 线性代数 · 直观理解矩阵 | 空间变换 / 特征值 / 特征向量
  • CERT/CC警告:新型HTTP/2漏洞“MadeYouReset“恐致全球服务器遭DDoS攻击瘫痪
  • 机械加工元件——工业精密制造的璀璨明珠
  • Day14: Flask太空站搭建指南:从零到超光速的Web开发之旅
  • git clone https://gh.llkk.cc/