现在的位置: 首页 > 综合 > 正文

Unity3D之AStarPathFinding插件的使用

2013年08月24日 ⁄ 综合 ⁄ 共 2485字 ⁄ 字号 评论关闭

  声明:   本博客文章原创类别的均为个人原创,版权所有。转载请注明出处: 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游戏里的一些简单脚本。


  

	public void Start ()
	{
		controller = GetComponent<Controller> ();
		seeker = GetComponent<Seeker> ();
		seeker.pathCallback += searchComplete;
		
		StartCoroutine(RepeatTrySearch());
	}
	
	
	IEnumerator RepeatTrySearch(){
		while(true){
		  TrySearchPath();
		  yield return new WaitForSeconds(searchRate);
		}
	}
	
	IEnumerator WaitForRepath(){
		if (waitingForRepath) yield break;
		 waitingForRepath = true;
	     yield return new WaitForSeconds(searchRate - (Time.time-lastRepath));
		 waitingForRepath = false;
		 TrySearchPath();
	}
	
	public void TrySearchPath(){
		if(Time.time - lastRepath >= searchRate && isCanSearch && isCanSearchAgain){
			lastRepath = Time.time;
		  	seeker.StartPath (transform.position, target.position);	
			isCanSearchAgain = false;
		}else {
		    StartCoroutine(WaitForRepath());	
		}
	}
	
	
	
	public void searchComplete (Path p)
	{
		path = p;
		nowPosition = 0;
		if (path != null) {
			vPath = path.vectorPath;	
			nextNode = vPath [nowPosition];
			Debug.Log ("Find Path:" + vPath.Count + "," + vPath [0]);
		} else {
			Debug.Log ("Find No Path");	
		}
		isCanSearchAgain = true;
		isMoveFinished = false;
	}

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

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

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


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


抱歉!评论已关闭.