简要
该组件算是unity官方提供的专门针对NavMeshAgent自动寻路系统做的一个扩展插件;针对于Unity内置的寻路系统,该扩展组件提供了额外的功能,例如可以动态Bake地形;动态拼接地形,物体可以从平地移动到墙面上等。本人从这里学习了相关的知识。此博客只是当做笔记给需要此功能的人做个学习例子(如有错误欢迎指出,持续更新中)
使用方式
将官方扩展组件下载并解压之后将Assets文件夹下所有的文件拷贝到工程中(Unity版本最低为5.6)
脚本作用说明:
NavMeshSourceTag:绑定该脚本的物体都可以动态烘焙
LocalNavMeshBuilder:在限定区域内添加NavMeshSourceTag的物体可以动态烘焙
NavMeshSurface:提供bake功能
NavMesh Link:连接两个点或面使其可以通过
例子
1.可以设置烘焙自定义的地形范围(局部烘焙),就不需要直接烘焙整个地图导致卡顿
·自身挂载NavMeshAgent组件和一个控制移动的脚本
using UnityEngine;
using UnityEngine.AI;
using DG.Tweening;
[RequireComponent(typeof(NavMeshAgent))]
public class PlayerCtrl : MonoBehaviour
{
Ray ray;
RaycastHit hitInfo;
NavMeshAgent agent;
private void Start()
{
agent = transform.GetComponent<NavMeshAgent>();
}
private Vector3 currentVec3 = Vector3.zero;
private void Update()
{
if (Input.GetMouseButtonUp(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray.origin, ray.direction, out hitInfo))
{
agent.destination = hitInfo.point;
}
}
}
}
·新建一个空的GameObject,挂载LocalNavMeshBuilder脚本,并将要寻路的物体拖拽到Tracked上
Tracked:设置跟踪的物体
Size:烘焙的范围(中心点基于跟踪的物体)
·给地形添加LocalNavMeshSourceTag脚本(挂载该脚本的物体才能够被LocalNavMeshBuilder烘焙)
这样就完成了局部烘焙的功能,只有鼠标点击的位置在烘焙范围内物体才会移动,并且烘焙范围会随着物体的移动而移动
2.动态地形烘焙
·创建三个Plane并全都挂载NavMeshSourceTag脚本(无需变为Static)
·新建一个空物体并挂载NavMeshSourceTag脚本,并限定其范围可以包裹住这三个Panel
·给Cube挂载NavMeshSurface脚本,并将CollectObject类型修改为Children,点击Bake
参数解释:
Agent Type:Agent类型(可以在Navigation面板中添加,并在这修改)
Collect Objects:All(烘焙所有带有NavMeshSourceTag脚本的物体)Volume(烘焙限定范围的地形)Children(烘焙自身及自身子物体)
Include Layers:可以通过的层级(可在Layers添加并在此处修改)
Use Geometry:可以选择用Render Mesh或碰撞器来Bake地形
Advanced:
Default Area:默认此地形的类型
Override Voxel Size:地形的精度(值越小精度越高,bake时间越长)
Override Tile Size:将地形分割成多少块(值越高bake时间越长)
·将中间的panel设置一个可以左右移动的动画
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using DG.Tweening;
[RequireComponent(typeof(NavMeshAgent))]
public class PlayerCtrl : MonoBehaviour
{
Ray ray;
RaycastHit hitInfo;
NavMeshAgent agent;
//动态Panel
Transform dynamicPanel;
NavMeshSurface surface;
private void Start()
{
agent = transform.GetComponent<NavMeshAgent>();
surface = transform.GetComponent<NavMeshSurface>();
dynamicPanel = GameObject.Find("Plane (3)").transform;
dynamicPanel.DOMove(Vector3.left * 4, 5).SetLoops(-1, LoopType.Yoyo).SetEase(Ease.Linear);
}
private Vector3 currentVec3 = Vector3.zero;
private void Update()
{
if (Input.GetMouseButtonUp(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray.origin, ray.direction, out hitInfo))
{
agent.destination = hitInfo.point;
}
}
}
}
·运行游戏,点击物体所在的另一个panel,这样,该物体就会移动到所在边缘并且等待中间panel连接之后移动其上最后移动到目的地(上传不了视频,不过简要那里的链接有相关的功能解释,本人只是实现了其效果)