Unity手游之路<九>自动寻路Navmesh之高级主题

向原创致敬http://blog.csdn.net/janeky/article/details/17492531

 

之前我们一起学习了如何使用Navmesh组件来实现最基本的角色自动寻路。今天我们再继续深入探索Navigation组件的高级功能。在本文中,你将了解到如何在两个隔离层自动生成寻路网格?如何手动指定寻路网格的路线?以及寻路网格层的应用。(本文所用到的模型皆来自Unity3d官网)。

  • 隔离层自动生成寻路网格

(源码scene1.unity)
1.创建Plane实例P1,P2,两者之间出现一条鸿沟。直接控制角色位移是无法通过的。
2.打开Navigation窗口,分别选中P1,P2,分别设置Navigation Static 和OffMeshLink Generatic
技术分享
3.保存场景,点击场景烘焙按钮Bake。结束后我们可以看到P1,P2除了自身生产寻路网格外,它们直接还生成了连接纽带。
4.添加角色模型Solder,为其添加NavMeshAgent(Component->Navigation->NavMeshAgent)
5.给Solder添加PlayerController脚本

[csharp] view plaincopy技术分享技术分享
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class PlayerController : MonoBehaviour  
  5. {  
  6.     private NavMeshAgent agent;  
  7.   
  8.     public bool setAgentWalkMask;//是否需要动态修改寻路层,在scene4的实例中要用到  
  9.   
  10.     void Start()  
  11.     {  
  12.         //获取寻路组件  
  13.         agent = GetComponent<NavMeshAgent>();  
  14.     }  
  15.   
  16.     void Update()  
  17.     {  
  18.         //鼠标左键点击  
  19.         if (Input.GetMouseButtonDown(0))  
  20.         {  
  21.             //摄像机到点击位置的的射线  
  22.             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);  
  23.             RaycastHit hit;  
  24.             if (Physics.Raycast(ray, out hit))  
  25.             {  
  26.                 //判断点击的是否地形  
  27.                 if (!hit.collider.tag.Equals("Plane"))  
  28.                 {  
  29.                     return;  
  30.                 }  
  31.                 //点击位置坐标  
  32.                 Vector3 point = hit.point;  
  33.                 //转向  
  34.                 transform.LookAt(new Vector3(point.x, transform.position.y, point.z));  
  35.                 //设置寻路的目标点  
  36.                 agent.SetDestination(point);  
  37.             }  
  38.         }  
  39.   
  40.         //播放动画  
  41.         if (agent.remainingDistance == 0)  
  42.         {  
  43.             animation.Play("Idle");  
  44.         }  
  45.         else  
  46.         {  
  47.             animation.Play("Run");  
  48.         }  
  49.           
  50.     }  
  51. }  

5.点击任意的位置,可以看到角色都能自动寻路过去
效果图
技术分享

  • 手动指定寻路网格方向

源码scene2.unity
1.scene1.unity的基础上,将P1,P2的OffMeshLink Generatic去除
2.在P1上新建一个空的GameObject Start,P2上新建一个空的GameObject End
3.选中start,为它添加Off Mesh Link组件 Component->Navigation->OffMeshLink
4.设置Off Mesh Link组件的属性,Start Point 为 start,End Point为end
5.烘焙场景。我们可以看到有一条纽带从start指向end
点击地图,可以看到角色如果要跨越P1和P2,一定是沿着我们手动创建的路径
技术分享

  • 导航网格障碍物 Navmesh Obstacle

之前我们都是用固定的物体作为障碍物,然后烘焙场景。Unity还提供了动态的障碍物。任何一个GameObject都可以添加Navmesh Obstacle组件,变成一个障碍物。具体步骤是Component->Navigation->Navmesh Obstacle.它有两个属性:半径和高度,可以设置跟你的物品差不多的体积大小。

  • 寻路网格层的应用

源码scene3.unity
玩过“3c”,“dota”这类游戏的同学都知道:地图上有上中下三条大道,不同的兵可能去的路不同。今天我们也做个类似的实例。
1.新建P1,P2,P3,P4等4个Plane,具体摆设形状见效果图
2.在Navigation窗口中,添加两个层Layers:Blue层和Red层
3.P1,P2的Navigation Layer设置为Default,P4的Navigation层设置为Red,P3设置为Blue
4.添加两个角色,设置他们的NavMeshAgent寻路层(NavMesh Walkable)。一个将Red层去掉,一个将Blue层去掉
5.点击P2的坐标,可以看到他们沿着不同的路径去目标点,一个走上层路线,一个走下层路线了。
效果图
技术分享

  • 动态改变寻路网格层

源码scene4.unity
在游戏中,我们很多时候都是需要根据不同的条件,选择不同的寻路路径。
1.在scene3.unity基础上做一下修改。只保留一个角色
2.新增两个按钮,“走上层”和“走下层”,在游戏运行时,可以改变Agent的寻路层。

[csharp] view plaincopy技术分享技术分享
  1. //动态设置寻路路径层  
  2.    void OnGUI()  
  3.    {  
  4.        if (!setAgentWalkMask)  
  5.        {  
  6.            return;  
  7.        }  
  8.        if (GUI.Button(new Rect(0, 0, 100, 50), "走下层"))  
  9.        {  
  10.            agent.walkableMask = 65;  
  11.        }  
  12.   
  13.        if (GUI.Button(new Rect(0, 100, 100, 50), "走上层"))  
  14.        {  
  15.            agent.walkableMask = 129;  
  16.        }  
  17.    }  

3.重新点击寻路,可以看到,选择不同的寻路层,角色的寻路路径也不同

技术分享

看到代码中的agent.walkableMask = 65和129,大家会比较迷惑,其实寻路层每一层都是2的幂,见下图
技术分享
所以上层的mask = Default(1)+Blue(128) = 129,下层的mak = Default(1)+Red(64) = 65

  • 总结

本文将寻路组件的各个细节都做了一次梳理,详细能帮大家熟练掌握各个特性,在实际项目中根据不同的需求熟练选择应用相关的特性。接下来我还会有一个更加详细的实例来贯穿所以的Navmesh特性,敬请期待!

  • 源码地址

http://pan.baidu.com/s/1jGoLITo

  • 参考资料

1.http://www.xuanyusong.com/
2.http://liweizhaolili.blog.163.com/
3.http://game.ceeger.com/Components/class-NavMeshAgent.html

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。