一開始搞這個問題很頭疼,無從下手。數組
一、敵人在隨機地點產生後,每一個敵人有要有本身自動的行走路線,目的地是保護地,並且行走路線要多樣化。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點找出行進路線。