量子计算9 发表于 2021-12-14 21:28

Unity Navigation系列二 动态导航

参考
[专栏精选]Unity中动态构建NavMesh
unity2021、新旧版本同时支持的 navigation navmeshagent ai寻路 静态烘焙,动态烘焙 动态障碍物 路径画线 使用教程
Unity - 新版NavMesh动态烘培
Unity NavMesh 动态烘焙绘制与随机取点
一、静态烘焙的局限性


Unity的新版NavMesh更加易用效率更高,而且支持动态烘培,这一点特别重要,可以很简单的就实现很多之前处理起来比较复杂的功能。

比如现在有个需求,怪物追随玩家,碰到陷阱后玩家跳过,怪物无法跳过碰到陷阱则死亡,但是后续的怪物可以踩着尸体过去。

这个功能之前的实现可能是这样的:在陷阱边缘停止导航,手动控制移动,碰到陷阱死亡停留原地变成地面…现在用新版NavMesh的动态烘培,只要很少的代码就可以实现了。

在障碍变化时,导航也在重新烘培,两个坦克会绕路继续干

Navigation系统有一个官方的扩展,虽然没有直接包含在Unity引擎的安装包里,但是是Unity官方提供的。”


image.png

点击这个,就会打开https://github.com/Unity-Technologies/NavMeshComponents

二、下载使用


打开https://github.com/Unity-Technologies/NavMeshComponents,在release中选择对应的版本:


image.png

下载解压以后,可以使用Unity打开该工程。如果要在已有的工程中使用,可以将Assets/NavMeshComponents目录复制到已有工程中。另外 Assets/Examples 目录中有示例场景。

GameObject中有扩展菜单


支持unity2020、2001及以后的实验性版本。需要通过package manager > add from url > 输入“com.unity.ai.navigation”地址,回车后会自动安装该组件
三、LocalNavMeshBuilder+NavMeshSourceTag


Examples/Scenes/drop_plank

1.LocalNavMeshBuilder


image.png

Tracked:设置跟踪的物体Size:烘焙的范围(中心点基于跟踪的物体)

上面图中那个盒子,表示的是动态烘焙的区域。我把例子改了一下,右侧红框的立方体被我挪出盒子范围,然后运行场景时,就走不上去了。
2.NavMeshSourceTag


需要动态生成NavMesh的物件添加NavMesh提供脚本NavMeshSourceTag.cs。作用是让LocalNavMeshBuilder知道这是物件是需要动态生成NavMesh的。

可以根据需要确定是否要勾选Mesh Renderer。如果该物件本身的作用就仅仅是寻路,那可以不勾选,也就是不可见。但如果该物件本身场景装饰作用,可以勾上。

运行场景时,按下空格键,会动态生成红色的板子,问题来了,红色板子要添加NavMeshSourceTag么?
public class SpawnPrefabOnKeyDown : MonoBehaviour{    public GameObject m_Prefab;    public KeyCode m_KeyCode;    void Update()    {      if (Input.GetKeyDown(m_KeyCode) && m_Prefab != null)      {            Instantiate(m_Prefab, transform.position, transform.rotation);      }    }}
观察一下这个Prefab,确实有:


image.png

如图,NavMeshSourceTag脚本默认是未激活的。在Enable Iff Sleeping中,会在红木板Sleeping之后再进行激活。这个很好理解,板子还在空中,未落到地面时,不应该进入导航烘焙列表。
    void Update()    {      if (m_Rigidbody == null || m_Behaviour == null)            return;      if (m_Rigidbody.IsSleeping() && !m_Behaviour.enabled)            m_Behaviour.enabled = true;      if (!m_Rigidbody.IsSleeping() && m_Behaviour.enabled)            m_Behaviour.enabled = false;    }3.例子4_sliding_window_infinite


这个例子,会动态生成地面和树,导航部分原理是一样的。随机生成算法的RandomInstancing值得研究。


通过Tracked属性,让这个盒子是动态移动的,这样就能控制烘焙范围,避免卡顿。另外,树和地面也不需要指定static


image.png

例子5_sliding_window_terrain是类似的,使用了地形。
四、NavMeshSurface


参考
转Unity5.6新功能动态烘焙 NavMesh之组件介绍
Unity Runtime NavMesh(运行时导航)总结,实现AI可以导航到墙壁(天花板)上

NavMeshSuface组件代表agent可以走的区域,定义世界中哪部分应该被bake成NavMesh 。一个场景中可以有多个NavMesh Surface组件。

例子1_multiple_agent_sizes


image.png

1.Collect Objects


image.png


All表示场景中有所物体都会拿来烘培,不管物体在哪里,在哪个层级。如下图,我在例子中Geometry层级外创建的cube,尽管NavMeshSurface是添加在Geometry上,但仍然会把这个cube当作障碍。

Children 只有自己及其子层级的物体才会加入烘培。这样新加的cube就不会当作障碍。


image.png


Volume 指定区域内才会烘培(不管是不是自己的孩子)


image.png

2.其它属性

Include Layers 可以选择用于生成NavMesh的layer。
[*]Use Geometry 用于生成NavMesh的几何体
Render Meshes 使用物体的Mesh和Terrain数据Physics Colliders 使用物体的Collider和Terrain数据(使用这个选项时,agent可以移动到物体边缘更近的地方)

五、NavMeshModifer + NavMeshModifer Volume


NavMesh Surface组件用来设置一片大范围内要被bake的物体的信息,而用NavMeshModifer组件可以对这些物体逐个进行微调。NavMesh Modifier Volume与NavMesh Modifier差不多,前者作用于对体积盒包围的所有物体(或物体的部分),后者只作用于自身及其子物体。

不过我下载的这个版本只有NavMeshModifer Volume???


image.png

Area Type 修改该物体及其所有子物体的Area类型。


image.png

Affected Agents 该组件影响的Agents。例如,你可以针对特定的Agent排除特定的障碍物。


image.png

六、NavMesh Link


NavMesh Link组件允许在两个区域间创建一条可通行的通道,NavMesh Link组件对于连接两个不同的NavMesh Surfaces是必须的。


image.png

Agent Type 可以使用这个NavMeshLink的Agent类型。Start Point 起点。相对于GameObject的位置。End Point 终点。相对于GameObject的位置。Swap按钮 交换起点和终点的位置。Align Transform按钮 将GameObject的位置移到起点和终点的中心,并且朝向终点的位置。Width 宽度。如果为0则通过两个点连接,如果大于0通过两条线连接。Cost Modifier 非负值时,通过这个链接的代价是Cost Modifier乘以终点的距离。Bidirectional 双向。不勾选时只能单向寻路。Area Type 设置该link的area类型。
页: [1]
查看完整版本: Unity Navigation系列二 动态导航