|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.AI;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 车辆管理类
|
|
|
|
|
/// 功能:车辆生成
|
|
|
|
|
/// 车辆AI
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class CarSys : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//计时器
|
|
|
|
|
private float timer = 0f;
|
|
|
|
|
//车辆种类列表
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//移动点列表
|
|
|
|
|
private Dictionary<string, Transform> MoveList = new Dictionary<string, Transform>();
|
|
|
|
|
//生成点列表
|
|
|
|
|
private Dictionary<string, Transform> BornList = new Dictionary<string, Transform>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Init()
|
|
|
|
|
{
|
|
|
|
|
CheckBornoint();
|
|
|
|
|
CheckMovePoint();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#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, NavMeshAgent agent)
|
|
|
|
|
{
|
|
|
|
|
if (lineName != "" && agent != null)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
Transform moveListParent = null;
|
|
|
|
|
MoveList.TryGetValue(lineName, out moveListParent);
|
|
|
|
|
Drive drive = agent.GetComponent<Drive>();
|
|
|
|
|
//添加前车检测器
|
|
|
|
|
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;
|
|
|
|
|
if (moveList[i] != null)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//向移动列表支点移动
|
|
|
|
|
agent.SetDestination(moveList[i].position);
|
|
|
|
|
//携程检测距离与路况
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
//**********重要***********//
|
|
|
|
|
yield return new WaitForSeconds(0.01f);
|
|
|
|
|
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);
|
|
|
|
|
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()
|
|
|
|
|
{
|
|
|
|
|
//随机获取出生点
|
|
|
|
|
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(Time.deltaTime);
|
|
|
|
|
timer += Time.deltaTime;
|
|
|
|
|
|
|
|
|
|
if (timer >= t)
|
|
|
|
|
{
|
|
|
|
|
timer = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
float checkTime = t / 5;
|
|
|
|
|
CreatCar(parent,checkTime);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StartCoroutine(RandomTimeCreat());
|
|
|
|
|
}
|
|
|
|
|
/// <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;
|
|
|
|
|
//car驾驶类赋值
|
|
|
|
|
Drive drive = car.GetComponent<Drive>();
|
|
|
|
|
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
|
|
|
|
|
NavMeshAgent agent = car.GetComponent<NavMeshAgent>();
|
|
|
|
|
if (agent != null)
|
|
|
|
|
{
|
|
|
|
|
StartCoroutine(CarMove(parent.name, agent));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|