unity 确定敌人行走路线

  一开始搞这个问题很头疼,无从下手。

    1、敌人在随机地点产生后,每个敌人有要有自己自动的行走路线,目的地是保护地,而且行走路线要多样化。

    2、敌人在看到玩家时,改变行走路线,向玩家的方向行进,且到了一定距离后停下对玩家进行射击。

    3、在玩家躲起来,即敌人无法看到玩家时,敌人要继续按行进路线走到保护地前。

  后来知道了Physics.Linecast "线性投射" 这个方法,从开始位置到结束位置做一个光线投射,如果与碰撞体交互,返回真。

  这样就有一个大体的思路:

    1、给定几个大小位置合适的区域,在这几个区域中随机产生敌人。

    2、在场景中设置20~30个合适的点,作为敌人的行走路线点,确保这些点不是两两可见的(即physics.Linecase值为true)。

    3、end标签作在保护地点上。

    4、下面的方法即为求以start点为起点的敌人的行走路线,road为中间点,way数组为路线。

    void init(){
        GameObject temp = start ;
        while(start.transform.name!=end.transform.name){
            float t = 100f ;
            for(int i=0; i<road.Length; i++){
                if(start==road[i]||road[i].tag!="other")    continue ;
                if(!Physics.Linecast(start.transform.position, road[i].transform.position)){
                    float t1 = Vector3.Angle(road[i].transform.position-start.transform.position, end.transform.position-start.transform.position) ;
                    if(Mathf.Abs(t1)<t){
                        t = Mathf.Abs(t1) ;
                        temp = road[i] ;
                    }
                }
            }
            way[wayCnt++] = temp ;
            start = temp ;
        }
    }

    5、既然求出了以start为起点的敌人的路线,那么就要得到当前敌人以那个点作为start点。

      下面的方法是找出距离当前敌人最近的tag为other的点。

    GameObject FindClosestPoint() {
        GameObject[] gos;
        gos = GameObject.FindGameObjectsWithTag("other");
        GameObject closest = null ;
        float distance = Mathf.Infinity;
        Vector3 position = transform.position;
        foreach (GameObject go in gos) {
            Vector3 diff = go.transform.position - position;
            float curDistance = diff.sqrMagnitude;
            if (curDistance < distance&&!Physics.Linecast(go.transform.position, position)) {
                closest = go;
                distance = curDistance;
            }
        }
        return closest;
    }

    6、有了上面的两个方法,就在这个敌人产生时确定了他的默认行进路线。下面的方法是让其在行进路线上移动。

    void changeRotation(){
        if(Vector3.Distance(IgnoreY(transform.position), IgnoreY(nextPoint.transform.position))>0.1f){
            Vector3 direction = (IgnoreY(nextPoint.transform.position)-IgnoreY(transform.position)).normalized ;
            Quaternion rotation = Quaternion.LookRotation(direction);
            transform.rotation = Quaternion.Lerp(transform.rotation, rotation, 0.1f);
            charCtl.SimpleMove(transform.forward*5) ;

        }else{
            nextPoint = way[index++] ;
        }
    }

    7、当敌人看到玩家时,也就是Physical.Linecast值为false,且在一定距离内

      即(!Physics.Linecast(man.transform.position, transform.position)&&(man.transform.position - transform.position).sqrMagnitude<1000f)

      敌人要改变行进方向,当到达一定距离时,进行射击。

Vector3 t = man.transform.position - transform.position;
if(!Physics.Linecast(man.transform.position, transform.position)&&t.sqrMagnitude<1000f){
  isLook = true ;
  Vector3 direction = (IgnoreY(man.transform.position)-IgnoreY(transform.position)).normalized ;
  Quaternion rotation = Quaternion.LookRotation(direction);
  transform.rotation = Quaternion.Lerp(transform.rotation, rotation, 0.1f);
  if(t.sqrMagnitude<200f){
    if(Time.time-now>fireStepTime){
      now = Time.time ;
      animation.Play("fire") ;
      Vector3 npos = tran.position ;
//     fireClone = (GameObject)Instantiate(fireObj, npos, transform.localRotation) ;
//     Destroy(fireClone, 0.05f) ;
      Ray ray = new Ray(npos, transform.forward);
      if(Physics.Raycast(ray, out hit)){
        if(hit.transform.tag=="manCon"){
          mainCam.SendMessage("getPlayerDamage", 10f) ;
        }
      }             
    }
  }
}

    8、当玩家再次消失在敌人视野中后,敌人要再次找到距离自己最近的点,并作为start点找出行进路线。

  

原文地址:https://www.cnblogs.com/xiaolongchase/p/3337310.html