C#实现三维自动寻址导航技术
  2023/12/6 11:30:22
  在unity中自带了一个自动寻路的功能,那就是Nav Mesh,在窗口(windows)-AI->导航(Navigation)打开(如没有请在windows-PakageManager-UnityRegistry下载),在使用Nav Mesh之前先简单介绍一下,Nav Mesh中有四个概念物体:
NavMesh Agent:理解为需要自己移动到目标,自动寻路的游戏物体
NavMesh:用来表示可以移动的地方,也就是寻路的 NavMesh Agent可以走的地方
Off-Mesh Link:用来控制当出现了不连续的地图,类似于断点,可以将两个断点连接起来
NavMesh Obstacle:这就是移动时,地图上的障碍物,对于Carve进行勾选,才可以动态烘培,这样可实现移动的障碍。

还有一个概念就是这个Nav Mesh是根据游戏物体上的Mesh Renderer且为static时来确定的,由于2D游戏不会涉及到Mesh Renderer,因此这个适合3D游戏。再来介绍一下导航窗口下的四个窗口
代理Agents窗口:这个窗口在旧版的导航几乎不用
区域Area窗口:这就是自定义区域,在区域中,数值越低优先级越高,可在对象窗口中的Navigation Areaz选择。
烘焙Bake窗口:对地图属性进行设置,然后进行烘焙出跨越行走的区域,包括:
Agent Radius:定义网格和地形边缘的距离
Agent Height:定义可以通行的最高度
Max Slope:定义可以爬上楼梯的最大坡度
Step Height:定义可以登上台阶的最大高度(最大高度要小于可通行的最大高度)
Drop Height:允许最大下落距离
Jump Distance:允许最大的跳跃距离
对象Object窗口:对象参数设置。
在了解完这四个窗口后就来进行一下效果演示
1.简单的导航系统:首先需要在移动的物体上添加 NavMesh Agent组件,
一个移动的C#脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;//引入命名空间
public class AutoMove : MonoBehaviour
{
  public GameObject target;//目标
  private NavMeshAgent Agent;//移动的对象
  void Start()
  {
    Agent = GetComponent();
    Agent.SetDestination(target.transform.position);
  }
  void Update(){}
}

随后在导航栏中自然把障碍物的状态设置为不可以移动区域 ,最后记得要在烘焙中点击bake,做完了简单的演示之后,再来看看较为复杂的导航功能。

2.跨越障碍物:先在烘焙窗口中设置好跳跃高度和坡度参数,使得障碍物能够被烘焙到可行走的地图中
跳跃的障碍物记得切换为跳跃区域。这里设置了Jump区域,可以在区域窗口中看到,Jump区域的优先级为2,其实我们使用的Jump区域只是我们自己规定的一个区域,意思就是能用走的区域,就不要走跳的区域,也就是说,你在平地也可以将区域设置为Jump区域,只不过人物会优先选择walkable区域,我们一般把突起的区域设置为Jump,并不是说设置了jump区域就一定要跳)

3.跳跃平台:当两个地图不连接的适合,我们就可以将两个需要连接平面的对象的勾选上,然后再设置烘焙中的高度和距离,点击烘焙,看到有很多连接点,再看看运行效果。
这种效果并没有达到我们想要的预期,我们应该先把取消勾选,然后创建出一个空Link对象再上面挂载Off Mesh Link组件,创建两个对象做为跳跃的起点和终点,并赋值,以上的效果都依赖与第一个书写的脚本,接下来更改脚本,实现人物到达鼠标点击地图的位置

4.到达点击位置:脚本如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;//引入命名空间
public class AutoMove : MonoBehaviour
{
  public GameObject target;//目标
  private NavMeshAgent Agent;//移动的对象
  void Start()
  {
    Agent = GetComponent();
   // Agent.SetDestination(target.transform.position);
  }
  void Update()
  {
    if(Input.GetMouseButtonDown(0))
    {
      Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);//从屏幕一点发射射线
      if(Physics.Raycast(ray, out RaycastHit hit))Agent.SetDestination(hit.point);
      //判断射线是否碰到物体,如果碰到,将会将碰到的信息返回给hit设置目标位置
    }
  }
}

5.可移动障碍物:
在遇到移动障碍物时,传统的依靠静态烘焙可行走地图的方法就行不通,下图可以明显的看见可行走的地图和移动的门并不在实时烘焙

因此就引入一个NavMesh Obstacle组件,在移动的障碍物上添加,此时就有躲避移动障碍的效果,如果勾选切割,并取消仅在静止时切割,就可以看到实时烘焙的可行走地面
以上就是Nav Mesh的基本操作,NavMeshComponents则是unity官方GitHub上的一套功能更强大的扩展了Navigation的工具。能做到更多例如动态烘焙,预设体和设置跳跃路径等。

如何安装
1.NavMeshComponents官方链接
2.下载下来
3.把Assets/NavMeshComponents复制到自己的项目内。
新版本的导航系统新加了四个脚本组件
1.NavMeshSurface(优先级比旧版本高)
这个组件我理解的是旧版代理和烘焙的结合版,在旧版中,一个地图只能烘焙一个可行走地面,也就是说所有人都是使用这一张导航地图,可是这个组件就可以实现一种角色对应一张地图
我们首先在代理窗口中添加了人物角色和怪物角色,怪物角色的跨越高度比人物角色高
随后创建了一个人物一个怪物,分别添加了Nav MeshAgent组件
再创建了一个SurfaceManager的空对象,用来挂载NavMeshSurface脚本组件,再该组件中选择不同的角色,可以看见代理中设置的参数,再分别点击bake,就可以烘焙出各自的行走地图
来看效果(点击移动脚本参考上方)
注意:也可以用代码控制bake大概做法就是先
Public NavMeshSurface navMeshSurface;//获取到需要生成的脚本组件对
navMeshSurface.BuildNavMesh();//就是代码生成可行走地图
2.NavMeshModifier:用来单独挂载再障碍物上,来修改可行走地图
修改了之后再看效果图,这样怪物就不能跨越指定障碍物了
3.NavMeshModifierVolume:这个就是指定立方体体积内的内容进行修改,功能与上方类似
4.NavMeshLink
这个脚本组件和旧版的类似,但是要比旧版本的方便,跨越直接创建一个物体挂载脚本
该脚本直接就有起点和终点,只需要设置即可,效果如下
如果不想要过渡的传送效果,还可以用代码控制,旧版同样适用
private NavMeshAgent agent ;//先获取对象
if (agent. is0n0ffMeshLink)//在update中判断
{
    agent.Complete0ffMeshLink() ;//直接完成链接
}
注意事项:
agent.velocity;//可以获取代理的速度,可以用来判断角色是否移动
原文链接:https://blog.csdn.net/qq_62947569/article/details/129853212
 [1] [2]

相关文章(向右看)..

·相关
C#unity定时延迟函数的常用
Unity如何使用HDRP,项目/图
Unity判断物体是否在摄像机视
UnityC#五种方法调用其他脚
C#协程的几种调用方法
u3d出现Autodesk.Fb/图
unity之HDRP性能质量最优/图
Unity提升画质的几点注意,U
nginx装逼:伪装隐藏网站扩展
unity使用GUI及时控制文字

·热点