Unity3D-NavMeshPath动态寻路(重点补充)

领导让做个动态寻路的效果,而不是简单的自动寻路。

意思是,首先Monster 检测hero的位置先自动寻路,如果hero位置不改变,说明刚才的寻路路径是正确的;如果hero位置改变,但是改变后的位置依然在旧的寻路路径上,也说明旧的寻路路径有用;但是如果hero的位置改变,而且已经不在刚才的寻路路径上,说明需要重新寻路。

ok,说清楚了效果,关键是如果得到旧的寻路路径,只要再遍历一下就好了。

问了一些群里的大神说,这是动态寻路,用一个插件,我给链接大家可以自己研究,

http://www.narkii.com/club/forum.php?mod=viewthread&tid=328657&extra=page%3D%257Bprevpage%257D&page=3

不过,实际上我们自己也可以做。

我上一个Nav教程中写了很多关于NavMeshPath的属性,是别人翻译过来的,但是还是不全,需要自己去读原API,给链接

http://docs.unity3d.com/ScriptReference/30_search.html?q=NavMeshAgent

ok,你会找到一个

NavMeshAgent.path

它就是,自动寻路的路径。打开之后,看到它返回一个NavMeshPath类型的路径。再看NavMeshPath类


有个corners属性,再点开,人家给了个例子,是求自动寻路的路径长度
using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    float PathLength(NavMeshPath path) {
        if (path.corners.Length < 2)
            return;
        
        Vector3 previousCorner = path.corners[0];
        float lengthSoFar = 0.0F;
        int i = 1;
        while (i < path.corners.Length) {
            Vector3 currentCorner = path.corners[i];
            lengthSoFar += Vector3.Distance(previousCorner, currentCorner);
            previousCorner = currentCorner;
            i++;
        }
        return lengthSoFar;
    }
}

写到这,大家旧明白了,corners是一个数组,记录了路径上的几个关键的点(注意,路径不是线,是几个关键点构成,线段是由点构成的嘛)
ok。我稍加改进,在自己的脚本中,打印一下路径
using System.Collections;

public class MonsterRun : MonoBehaviour {
	private NavMeshAgent agent;
	private GameObject hero;
	// Use this for initialization
	void Start () {
		agent = GetComponent<NavMeshAgent> ();
		hero = GameObject.Find ("Hero");
	}
	
	// Update is called once per frame
	void Update () {
		//Debug.Log ("Monster find hero's point :" + hero.transform.position.x + " " + hero.transform.position.z);
		Vector3 vector=new Vector3 (hero.transform.position.x-1, transform.position.y, hero.transform.position.z-1);
		//Vector3 vector = hero.transform.position;
		transform.LookAt (vector);
		agent.SetDestination(vector); 
		NavMeshPath path = agent.path;
		Debug.Log (vector+" "+path.corners.Length+" "+path.status);
		for (int i=0; i<path.corners.Length; i++) {
			Debug.Log(i+"= "+path.corners[i]);
		}
	}
}

运行结果

其中(29,1.2,29)是目标点,它画了8个点,8个点,大家可以看到,依次向目标点靠近。
注:如果你的Monster和Hero距离很短,那可能只存储起始位置 length=1 这种情况很多 至少我测试出来很多,我自动把它屏蔽了
OK了,最核心的一步:拿到路径已经做完了,下一步是,判断是否更新。

(ps:待会继续,我现在才理解到这!)

补全一下,动态寻路得脚本

	void Start(){
		agent = GetComponent<NavMeshAgent> ();
		hero = GameObject.Find ("Sam");
		lifeValue = 100;
		targetPos=new Vector3 (0 , 0, 0);
		StartCoroutine(findOrFight());
	}

	//Moster寻路或者打架
	private IEnumerator findOrFight(){
		while (true) {		
			yield return new WaitForSeconds(findWayTime);
			if(!islaying){
				if(heroDistance(distance)){
					//hero在monster的范围之内 可以打  停止寻路
					//Debug.Log("Fight");
					isFindWay=false;
					//agent.Stop();
					//开始攻击
					if(!isAttack){
						StartCoroutine(attackHero());
					}
					
				}else{
					//需要寻路
					Debug.Log("Find");
					animation.Play("walk"); 
					findWay();
				}
			}

		}
	}
	//wait for time
	private IEnumerator WaitSomeSeconds(float time)  
	{  
		yield return new WaitForSeconds(time); 
	}  


  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值