一开始搞这个问题很头疼,无从下手。数组
一、敌人在随机地点产生后,每一个敌人有要有本身自动的行走路线,目的地是保护地,并且行走路线要多样化。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点找出行进路线。