using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; /// /// 车辆管理类 /// 功能:车辆生成 /// 车辆AI /// /// public class CarSys : MonoBehaviour { //车辆种类列表 public GameObject[] carTypeList; //已生成车辆列表 //public List carList=new List(200); [HideInInspector] public Dictionary carList = new Dictionary(); // public int CarID = 0; //车辆检测开关 public bool openCheck = true; public static CarSys Instance = null; [HideInInspector] public bool canCreatCar = true; //移动点列表 private Dictionary MoveList = new Dictionary(); //生成点列表 private Dictionary BornList = new Dictionary(); public void Init() { Instance = this; //检索创建车的地点 CheckBornoint(); //检索车辆移动点 CheckMovePoint(); //开启创建携程 StartCoroutine(RandomTimeCreat(1)); StartCoroutine(RandomTimeCreat(2)); } #region 车辆AI //检索汽车生成点 public void CheckBornoint() { GameObject[] bornPoints = GameObject.FindGameObjectsWithTag("BornPoint"); for (int i = 0; i < bornPoints.Length; i++) { BornList.Add(bornPoints[i].name, bornPoints[i].transform); } } //检索移动列表 public void CheckMovePoint() { GameObject[] moveObjs = GameObject.FindGameObjectsWithTag("MoveList"); for (int i = 0; i < moveObjs.Length; i++) { MoveList.Add(moveObjs[i].name, moveObjs[i].transform); } } //车辆AI移动函数 public IEnumerator CarMove(string lineName, Drive drive) { if (lineName != "" && drive != null) { Transform moveListParent = null; MoveList.TryGetValue(lineName, out moveListParent); NavMeshAgent agent = drive.agent; //添加前车检测器 GameObject go =Resources.Load("Prefab/DistanceCheck"); GameObject go_c= Instantiate(go, drive.transform); go_c.transform.position = drive.transform.position + (drive.transform.forward.normalized * 6); DistanceChecker checker = go_c.GetComponent(); //float t = 0; if (moveListParent != null) { Transform[] moveList = new Transform[moveListParent.childCount]; //遍历移动列表 for (int i = 0; i < moveListParent.childCount; i++) { moveList[i] = moveListParent.GetChild(i); //路径方向 Vector3 Dir = (moveList[i].transform.position - drive.transform.position).normalized; drive.driveDir = Dir; drive.dir_trans = moveList[i]; if (moveList[i] != null) { //向移动列表支点移动 agent.SetDestination(moveList[i].position); //携程检测距离与路况 while (true) { //**********重要***********// yield return new WaitForSeconds(0.02f); drive.drivetime += Time.deltaTime; float distance = Vector3.Distance(agent.transform.position, moveList[i].position); if (drive.drivetime >= drive.checktime) { drive.isnormalDrive = checker.IsNoObstacle(); } //状态判断 优先级顺序为:受障碍、到达终点、弯道、直线 if (drive.isnormalDrive == false && drive.dirveState != DriveState.Turn) { drive.dirveState = DriveState.Stop; } else if(distance <= 0.5f) { drive.dirveState = DriveState.PointOver; break; } else if(distance <= 20f && distance > 0.5f) { drive.dirveState = DriveState.Turn; } else if (distance > 20f) { drive.dirveState = DriveState.Line; } } } } //回收车辆 carList.Remove(drive.carId); // Destroy(agent.gameObject); ObjectPool.Instance.Unspawn(agent.gameObject); GameRoot.Instance.infoWnd.SetCarOutText(1); } } } //检测前方车辆 public bool CheckFrontCar(Drive drive) { if (drive.FrontCar == null) return false; if (Vector3.Distance(drive.transform.position, drive.FrontCar.transform.position) < Const.SafeDistance) { return true; } return false; #region MyRegion //for (int i = 0; i < carList.Count; i++) //{ // Vector3 target = carList[i].transform.position; // Vector3 dir = target - drive.transform.position; // drive.dot = Vector3.Dot(drive.transform.forward.normalized,dir.normalized); // //判断是否前方有小于安全距离的车辆 // if (Vector3.Dot(drive.transform.forward.normalized, dir.normalized) > Mathf.Cos(Mathf.PI/6) && Vector3.Distance(target, drive.transform.position) <= Const.SafeDistance) // { // Debug.Log(drive.gameObject.name); // return true; // } // else // { // continue; // } //} //return false; #endregion } #endregion #region 汽车随机生成 int tempindex; /// /// 生成汽车递归携程,在GameRoot中启用一次即可 /// /// public IEnumerator RandomTimeCreat() { //计时器 float timer = 0f; //随机获取出生点 Transform parent = null; int pointIndex = Random.Range(1, BornList.Count + 1); if (tempindex == pointIndex) { StartCoroutine(RandomTimeCreat()); yield break; } tempindex = pointIndex;//防重复 BornList.TryGetValue("0" + pointIndex.ToString(), out parent); if (parent != null) { //随机时间 float t = Random.Range(Const.RefreshCarminTime, Const.RefreshCarmaxTime); //Debug.Log(t); while (true) { yield return new WaitForSeconds(0.02f); timer += Time.deltaTime; if (timer >= t) { timer = 0; break; } } float checkTime = t / 5; CreatCar(parent,checkTime); } StartCoroutine(RandomTimeCreat()); } public IEnumerator RandomTimeCreat(int index) { if (!canCreatCar) yield break; //计时器 float timer = 0f; //随机获取出生点 Transform parent = null; int pointIndex = index; BornList.TryGetValue("0" + pointIndex.ToString(), out parent); if (parent != null) { //随机时间 float t = Random.Range(Const.RefreshCarminTime, Const.RefreshCarmaxTime); //Debug.Log(t); while (true) { yield return new WaitForSeconds(0.02f); timer += Time.deltaTime; if (timer >= t) { timer = 0; break; } } float checkTime = t / 5; CreatCar(parent, checkTime); } switch (pointIndex) { case 1: pointIndex = 3; break; case 2: pointIndex = 4; break; case 3: pointIndex = 1; break; case 4: pointIndex = 2; break; } StartCoroutine(RandomTimeCreat(pointIndex)); } /// /// 汽车生成函数 /// /// 生成之后的父物体 /// 生成后开始行驶检测的时间 public void CreatCar(Transform parent,float checktime) { // 随机创建车辆种类 int carIndex = Random.Range(0, carTypeList.Length - 1); //实例化车辆 //GameObject car = GameObject.Instantiate(carTypeList[carIndex], parent.position, Quaternion.identity, parent); //car.transform.eulerAngles = parent.eulerAngles; //对象池优化创建实例 GameObject car = ObjectPool.Instance.Spawn(carTypeList[carIndex].name, parent); //NavAgent赋值 NavMeshAgent _agent = car.GetComponent(); //car驾驶类赋值 Drive drive = car.GetComponent(); drive.agent = _agent; drive.carId = CarID; drive.checktime = checktime; carList.Add(CarID, drive.gameObject); CarID++; if (drive.carId != 0) { GameObject go = null; carList.TryGetValue(drive.carId - 1, out go); drive.FrontCar = go; } //统计数量更新 GameRoot.Instance.infoWnd.SetCarInText(1);//+1 //执行寻路AI if (drive.agent != null) { StartCoroutine(CarMove(parent.name, drive)); } } #endregion public void StopCreatCar() { canCreatCar = false; } }