Unity3D之AStarPathFinding插件的使用

  声明:   本博客文章原创类别的均为个人原创,版权所有。转载请注明出处: http://blog.csdn.net/ml3947,另外本人的个人博客:http://www.wjfxgame.com


  对于AStarPathFinding,很多人应该不会陌生。这个算是Unity3D里最好用的寻径插件了。不论是3D游戏,还是2D游戏,我们都可以使用它来进行A*算法的寻径。之前翻译的“使用免费工具进行2D游戏开发”的教程中本来应该有一节是AStarPathFinding寻径的,但是在这个教程翻译了三节之后,发现后面其实作者只是单纯把脚本什么的都给出下载地址,并未做介绍,而对Orthello的介绍在前面几节就结束了,所以就没有继续翻译。这里另外开一篇文章来单独介绍寻径。


  下面我们来看看,应该如何使用AStarPathFinding


  首先制作一个游戏场景。

  

  大家可以看到,这个是使用了一个Terrain,然后放置了几个房子和灯光以及树木等。

  

  我们创建一个空的Object,然后通过Component->Pathfinding->PathFinder添加脚本。这个是AStarPathFinder里最重要的脚本。将它改名为AStar。


  


  我们可以从右边看到有很多的栏目。

  其实寻径的原理,还是以网格的形式分布到地面,排除掉一些障碍物的相应的层,亦或者进行高度测试使得一定的高度不可行走。然后使用AStar寻径算法来寻找最短的路径。

  首先创建一个Grid Graph


  

  然后在这边调整网格的数目和大小。

  对于我们的3D游戏而言,网格的大小可以就设置为1( 2d游戏通常根据地图单元格大小来设置)。然后设置WidthDepth调整整个网格的大小。记住高度一定要与地形高度相同。

  最后点最下面的Scan。会搜索出所有可行走的路径,然后以某种颜色的形式显示在网格上。


  这里有几个很重要的参数。

  首先是Max ClimbClimb Axis。这个是指的最大攀爬的高度以及攀爬的轴的方向。通常而言,这个轴一定要与地形垂直,不然地面所有地方将无法通过。


  然后是Collision Test。这里是在寻径中对碰撞的一些检测。

  

  

  例如上图,我们对Default层进行了碰撞的检测,那么在寻径的时候,路径将不会通过这个帐篷的周边。


  


  我们看看内部,内部出了中间放置了一盘食物的位置为寻径无法通过的,其他地方都是可以通过的。


  


  当我们把Collision Test取消选中,然后重新Scan,那么在寻径中,整个帐篷的范围将都列入可行走的范围。


  这里要记住寻径上网格的可移动的范围,并不代表你的角色可以从这些范围行走。它只代表的,寻径算法将把这些范围列入为可通过的。然后,如果你的角色跟帐篷有碰撞,那么即使AStar计算出的路径要穿做帐篷,你的角色也是无法做到的。


  当AStar的PathFinder找到路径是,会在Scene中显示一条绿线。

  

  这条绿线就是寻找到的路径。


  


  同样的,通过限制图层碰撞等,我们也可以在2D游戏中使用AStarPathFinding。如上图,虽然绿线不是很清晰,但我们依然可以看到怪物走到我们角色的路径。


  下面我们来看一下,找到路径之后,怎么对路径进行处理。这里是上面2D游戏里的一些简单脚本。


  

[csharp]  view plain copy
  1. public void Start ()  
  2. {  
  3.     controller = GetComponent<Controller> ();  
  4.     seeker = GetComponent<Seeker> ();  
  5.     seeker.pathCallback += searchComplete;  
  6.       
  7.     StartCoroutine(RepeatTrySearch());  
  8. }  
  9.   
  10.   
  11. IEnumerator RepeatTrySearch(){  
  12.     while(true){  
  13.       TrySearchPath();  
  14.       yield return new WaitForSeconds(searchRate);  
  15.     }  
  16. }  
  17.   
  18. IEnumerator WaitForRepath(){  
  19.     if (waitingForRepath) yield break;  
  20.      waitingForRepath = true;  
  21.      yield return new WaitForSeconds(searchRate - (Time.time-lastRepath));  
  22.      waitingForRepath = false;  
  23.      TrySearchPath();  
  24. }  
  25.   
  26. public void TrySearchPath(){  
  27.     if(Time.time - lastRepath >= searchRate && isCanSearch && isCanSearchAgain){  
  28.         lastRepath = Time.time;  
  29.         seeker.StartPath (transform.position, target.position);   
  30.         isCanSearchAgain = false;  
  31.     }else {  
  32.         StartCoroutine(WaitForRepath());      
  33.     }  
  34. }  
  35.   
  36.   
  37.   
  38. public void searchComplete (Path p)  
  39. {  
  40.     path = p;  
  41.     nowPosition = 0;  
  42.     if (path != null) {  
  43.         vPath = path.vectorPath;      
  44.         nextNode = vPath [nowPosition];  
  45.         Debug.Log ("Find Path:" + vPath.Count + "," + vPath [0]);  
  46.     } else {  
  47.         Debug.Log ("Find No Path");   
  48.     }  
  49.     isCanSearchAgain = true;  
  50.     isMoveFinished = false;  
  51. }  

  这是一个重复搜索路径的代码。由于我们的角色在不停的移动,所以怪物需要在一定时间内,改变搜索目标地点,进行二次寻径。

  寻径完成后,我们可以通过path.vectorPath得到一个path数组,里面是一个List<Vector3>类型的链表。记载着路径中的每一个点的坐标。我们可以进行逐个点的移动和处理。

  这就是一个简单的AStar寻径的过程了。


  转载请注明出处:http://blog.csdn.net/ml3947

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值