You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

363 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
/// <summary>
/// 车辆管理类
/// 功能:车辆生成
/// 车辆AI
///
/// </summary>
public class CarSys : MonoBehaviour
{
//车辆种类列表
public GameObject[] carTypeList;
//已生成车辆列表
//public List<GameObject> carList=new List<GameObject>(200);
[HideInInspector]
public Dictionary<int, GameObject> carList = new Dictionary<int, GameObject>();
//
public int CarID = 0;
//车辆检测开关
public bool openCheck = true;
public static CarSys Instance = null;
[HideInInspector]
public bool canCreatCar = true;
//移动点列表
private Dictionary<string, Transform> MoveList = new Dictionary<string, Transform>();
//生成点列表
private Dictionary<string, Transform> BornList = new Dictionary<string, Transform>();
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<GameObject>("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<DistanceChecker>();
//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;
/// <summary>
/// 生成汽车递归携程在GameRoot中启用一次即可
/// </summary>
/// <returns></returns>
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));
}
/// <summary>
/// 汽车生成函数
/// </summary>
/// <param name="parent">生成之后的父物体</param>
/// <param name="checktime">生成后开始行驶检测的时间</param>
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<NavMeshAgent>();
//car驾驶类赋值
Drive drive = car.GetComponent<Drive>();
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;
}
}