unity 肯定敵人行走路線

  一開始搞這個問題很頭疼,無從下手。數組

    一、敵人在隨機地點產生後,每一個敵人有要有本身自動的行走路線,目的地是保護地,並且行走路線要多樣化。spa

    二、敵人在看到玩家時,改變行走路線,向玩家的方向行進,且到了必定距離後停下對玩家進行射擊。code

    三、在玩家躲起來,即敵人沒法看到玩家時,敵人要繼續按行進路線走到保護地前。orm

  後來知道了Physics.Linecast "線性投射" 這個方法,從開始位置到結束位置作一個光線投射,若是與碰撞體交互,返回真。blog

  這樣就有一個大致的思路:get

    一、給定幾個大小位置合適的區域,在這幾個區域中隨機產生敵人。animation

    二、在場景中設置20~30個合適的點,做爲敵人的行走路線點,確保這些點不是兩兩可見的(即physics.Linecase值爲true)。it

    三、end標籤做在保護地點上。io

    四、下面的方法即爲求以start點爲起點的敵人的行走路線,road爲中間點,way數組爲路線。ast

    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 ;
        }
    }

    五、既然求出了以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;
    }

    六、有了上面的兩個方法,就在這個敵人產生時肯定了他的默認行進路線。下面的方法是讓其在行進路線上移動。

    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++] ;
        }
    }

    七、當敵人看到玩家時,也就是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) ;
        }
      }             
    }
  }
}

    八、當玩家再次消失在敵人視野中後,敵人要再次找到距離本身最近的點,並做爲start點找出行進路線。

相關文章
相關標籤/搜索