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.
506 lines
15 KiB
506 lines
15 KiB
using DG.Tweening;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public enum CarDriveStatu
|
|
{
|
|
正常,
|
|
减速,
|
|
加速,
|
|
超车,
|
|
异常,
|
|
怠速,
|
|
等红灯,
|
|
}
|
|
|
|
|
|
public class Car : MonoBehaviour
|
|
{
|
|
public int ID;
|
|
[Header("车牌")]
|
|
public string CarIDCard;
|
|
[Header("行驶状态")]
|
|
public CarDriveStatu driveStatu;
|
|
[Header("是否可超车")]
|
|
public bool canOverTake=true;
|
|
[Header("速度")]
|
|
private float _Speed = 35;
|
|
[Header("车表温度")]
|
|
public float _Temperature = 45;
|
|
[Header("转弯半径")]
|
|
public float _TurnRaduis = 0;
|
|
[Header("是否通过ETC")]
|
|
public bool IsCrossETC = false;
|
|
[Header("行驶道路父物体")]
|
|
public Transform DriveRoad = null;
|
|
[Header("是否变道")]
|
|
public bool IsChangeRoad=false;
|
|
[Header("车类型")]
|
|
public int CarType; //1-轿车 2-SUV 3-货车
|
|
[Header("是否正常行驶中")]
|
|
public bool isNormalDrive = true;
|
|
[Header("超车检测")]
|
|
public bool isOpenOverCheck;
|
|
[Header("计时器")]
|
|
public float timer = 0f;
|
|
[Header("堵车后的超车时间")]
|
|
private float ChaoCheTime = 2f;
|
|
[Header("最近遇到的障碍物")]
|
|
public Transform wall=null;
|
|
[Header("超车检测方向")]
|
|
public WayDir wayDir = WayDir.左侧;
|
|
[Header("目标点")]
|
|
public Vector3 MovePoint;
|
|
[Header("用于判断超速的车速")]
|
|
public float overSpeed;
|
|
[HideInInspector]
|
|
[Header("是否已被检测")]
|
|
public bool isChecked = false;
|
|
[HideInInspector]
|
|
[Header("检测框")]
|
|
public GameObject kuang;
|
|
[Header("是否闯红灯")]
|
|
public bool iscrossRedLight = false;
|
|
|
|
|
|
|
|
private Vector3 Dir;
|
|
int currentMoveIndex=0;
|
|
Transform[] moveList;
|
|
Transform currentMovePoint;
|
|
bool isDrive = false;
|
|
public Vector3 moveOffset=Vector3.zero;
|
|
|
|
private Ray ray1=new Ray();
|
|
private Ray ray2=new Ray();
|
|
private Ray ray3 = new Ray();
|
|
private Rigidbody rig;
|
|
|
|
|
|
|
|
private void RandomTemperature()
|
|
{
|
|
float temp = UnityEngine.Random.Range(-5, 5);
|
|
_Temperature += temp;
|
|
}
|
|
|
|
private void SetOverSpeed()
|
|
{
|
|
if (GameManagerForZhuanWan.Instance == null) return;
|
|
if (GameManagerForZhuanWan.Instance.isNormalRoadState)
|
|
{
|
|
overSpeed = UnityEngine.Random.Range(80, 110);
|
|
}
|
|
else
|
|
{
|
|
|
|
overSpeed = UnityEngine.Random.Range(DriveManager.Instance.OverSpeedMaxValue - 15, DriveManager.Instance.OverSpeedMaxValue-10);
|
|
|
|
}
|
|
}
|
|
|
|
public void Init()
|
|
{
|
|
|
|
ID = UnityEngine.Random.Range(0, 9000);
|
|
|
|
SetOverSpeed();
|
|
|
|
|
|
rig = this.GetComponent<Rigidbody>();
|
|
RandomTemperature();
|
|
if (DriveRoad != null)
|
|
{
|
|
|
|
moveList = new Transform[DriveRoad.childCount];
|
|
for (int i = 0; i < moveList.Length; i++)
|
|
{
|
|
moveList[i] = DriveRoad.GetChild(i);
|
|
}
|
|
currentMovePoint = moveList[currentMoveIndex];
|
|
isDrive = true;
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
|
|
DriveRoad = null;
|
|
currentMoveIndex = 0;
|
|
|
|
}
|
|
|
|
private void ResetCar()
|
|
{
|
|
_Speed = Const.正常速度;
|
|
timer = 0;
|
|
moveOffset = Vector3.zero;
|
|
wall = null;
|
|
driveStatu = CarDriveStatu.正常;
|
|
|
|
SetOverSpeed();
|
|
}
|
|
|
|
private float daisuSpeed = 15;
|
|
private void FixedUpdate()
|
|
{
|
|
if (!isDrive) return;
|
|
|
|
MovePoint = currentMovePoint.position;
|
|
|
|
// Dir = ((currentMovePoint.position+moveOffset) - transform.position).normalized;
|
|
Dir = ((new Vector3(currentMovePoint.position.x, transform.position.y, currentMovePoint.position.z) + moveOffset) - transform.position).normalized;
|
|
|
|
Vector3 lookDir = new Vector3(currentMovePoint.position.x+moveOffset.x, transform.position.y, currentMovePoint.position.z+ moveOffset.z) - transform.position;
|
|
Quaternion rot = Quaternion.LookRotation(lookDir);
|
|
|
|
float distance = Vector3.Distance(transform.position, currentMovePoint.position + moveOffset);
|
|
|
|
|
|
if (distance <= 1.5f)
|
|
{
|
|
//更新点位
|
|
currentMoveIndex++;
|
|
currentMovePoint = moveList[currentMoveIndex];
|
|
|
|
if (currentMoveIndex== moveList.Length-1&&distance<=1.5f)
|
|
{
|
|
isDrive = false;
|
|
ResetCar();
|
|
//回收车辆
|
|
ObjectPool.Instance.Unspawn(gameObject);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
driveStatu = DriveCheck();
|
|
switch (driveStatu)
|
|
{
|
|
case CarDriveStatu.等红灯:
|
|
_Speed = 0;
|
|
rig.velocity = Vector3.zero;
|
|
break;
|
|
|
|
case CarDriveStatu.怠速:
|
|
daisuSpeed -= 2.5f * Time.deltaTime;
|
|
daisuSpeed=Mathf.Clamp(daisuSpeed, 5, 100);
|
|
_Speed = daisuSpeed;
|
|
//this.moveOffset.x = 0;
|
|
rig.velocity = Dir * _Speed;
|
|
transform.DORotate(new Vector3(rot.eulerAngles.x, rot.eulerAngles.y, rot.eulerAngles.z), 0.5f, RotateMode.Fast);
|
|
OverSpeedRandom(false);
|
|
overSpeed = 20f;
|
|
break;
|
|
|
|
case CarDriveStatu.正常:
|
|
daisuSpeed = 15;
|
|
_Speed = DriveManager.Instance._speed;
|
|
//this.moveOffset.x = 0;
|
|
rig.velocity = Dir * _Speed;
|
|
transform.DORotate(new Vector3(rot.eulerAngles.x, rot.eulerAngles.y, rot.eulerAngles.z), 0.5f, RotateMode.Fast);
|
|
OverSpeedRandom(true);
|
|
break;
|
|
case CarDriveStatu.减速:
|
|
_Speed =0;
|
|
rig.velocity = Vector3.zero;
|
|
OverSpeedRandom(false);
|
|
overSpeed = 0f;
|
|
break;
|
|
case CarDriveStatu.加速:
|
|
rig.velocity = Dir * _Speed*1.5f;
|
|
transform.DORotate(new Vector3(rot.eulerAngles.x, rot.eulerAngles.y, rot.eulerAngles.z), 0.5f, RotateMode.Fast);
|
|
break;
|
|
case CarDriveStatu.异常:
|
|
OverSpeedRandom(false);
|
|
//rig.velocity = Vector3.zero;
|
|
break;
|
|
case CarDriveStatu.超车:
|
|
//_Speed = Const.正常速度;
|
|
OverSpeedRandom(true);
|
|
float x = moveList[currentMoveIndex + 1].position.x - moveList[currentMoveIndex].position.x;
|
|
float z = moveList[currentMoveIndex + 1].position.z - moveList[currentMoveIndex].position.z;
|
|
//超车改道
|
|
if (wayDir == WayDir.左侧)
|
|
{
|
|
|
|
if (x > z)
|
|
{
|
|
this.moveOffset.z = 4.5f;
|
|
this.moveOffset.x = 0f;
|
|
}
|
|
else
|
|
{
|
|
this.moveOffset.z = 0f;
|
|
this.moveOffset.x = -4.5f;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
if (x > z)
|
|
{
|
|
this.moveOffset.z = -4.5f;
|
|
this.moveOffset.x = 0;
|
|
}
|
|
else
|
|
{
|
|
this.moveOffset.z = 0f;
|
|
this.moveOffset.x = 4.5f;
|
|
}
|
|
}
|
|
|
|
rig.velocity = Dir * _Speed;
|
|
transform.DORotate(new Vector3(rot.eulerAngles.x, rot.eulerAngles.y, rot.eulerAngles.z), 0.75f);
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
private void OverSpeedRandom(bool ischeck)
|
|
{
|
|
//速度变化
|
|
if (Time.frameCount % 25 == 0)
|
|
{
|
|
|
|
if (ischeck)
|
|
{
|
|
|
|
// float randomSP = UnityEngine.Random.Range(0.05f, 0.2f);
|
|
if (overSpeed <= DriveManager.Instance.OverSpeedMaxValue)
|
|
{
|
|
// overSpeed = UnityEngine.Random.RandomRange(DriveManager.Instance.OverSpeedMaxValue - 5, DriveManager.Instance.OverSpeedMaxValue + 5);
|
|
float value = UnityEngine.Random.Range(-1f, 1f);
|
|
overSpeed += value;
|
|
overSpeed = Mathf.Clamp(overSpeed, 80, 200);
|
|
}
|
|
else
|
|
{
|
|
overSpeed = UnityEngine.Random.RandomRange(DriveManager.Instance.OverSpeedMaxValue - 10f, DriveManager.Instance.OverSpeedMaxValue + 5f);
|
|
//float value = UnityEngine.Random.Range(-1f, 0.5f);
|
|
//overSpeed += value;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
overSpeed = 0f;
|
|
// overSpeed = Mathf.Clamp(overSpeed, 0, 200);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 行驶状态检测
|
|
/// </summary>
|
|
private CarDriveStatu DriveCheck()
|
|
{
|
|
if (!isNormalDrive) return CarDriveStatu.异常;
|
|
if (driveStatu == CarDriveStatu.异常) return CarDriveStatu.异常;
|
|
|
|
//Debug.DrawLine(transform.position, transform.forward + new Vector3(45, 0, 0));
|
|
|
|
ray1.origin = transform.position;
|
|
ray1.direction = transform.forward;
|
|
ray2.origin = transform.position;
|
|
ray2.direction = -transform.right;
|
|
ray3.origin = transform.position;
|
|
ray3.direction = transform.right;
|
|
//ray4.origin = transform.position;
|
|
//ray4.direction = transform.right;
|
|
//ray5.origin = transform.position;
|
|
//ray5.direction = transform.right;
|
|
RaycastHit hitInfo1;
|
|
RaycastHit hitInfo2;
|
|
RaycastHit hitInfo3;
|
|
//是否可超车检测
|
|
if (isOpenOverCheck == false)
|
|
{
|
|
canOverTake = false;
|
|
}
|
|
else
|
|
{
|
|
if (wayDir == WayDir.左侧)
|
|
{
|
|
if (Physics.Raycast(ray2, out hitInfo2, 15))
|
|
{
|
|
if (hitInfo2.transform.gameObject.tag == "Car")
|
|
{
|
|
if (hitInfo2.transform.gameObject.GetComponent<Car>().isNormalDrive == false)
|
|
{
|
|
canOverTake = true;
|
|
}
|
|
else
|
|
{
|
|
canOverTake = false;
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
canOverTake = true;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
canOverTake = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Physics.Raycast(ray3, out hitInfo3, 15))
|
|
{
|
|
if (hitInfo3.transform.gameObject.tag == "Car")
|
|
{
|
|
if (hitInfo3.transform.gameObject.GetComponent<Car>().isNormalDrive == false)
|
|
{
|
|
canOverTake = true;
|
|
}
|
|
else
|
|
{
|
|
canOverTake = false;
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
canOverTake = true;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
canOverTake = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//是否需超车检车
|
|
if (wall != null )
|
|
{
|
|
timer += Time.deltaTime;
|
|
if (canOverTake&&timer>=ChaoCheTime)
|
|
{
|
|
if (Vector3.Distance(wall.position, transform.position) > 7)
|
|
{
|
|
//wall = null;
|
|
//timer = 0f;
|
|
//return CarDriveStatu.正常;
|
|
_Speed = DriveManager.Instance._speed;
|
|
}
|
|
else
|
|
{
|
|
return CarDriveStatu.超车;
|
|
}
|
|
return CarDriveStatu.超车;
|
|
}
|
|
else
|
|
{
|
|
return CarDriveStatu.减速;
|
|
}
|
|
|
|
}
|
|
//前方车辆检测
|
|
if (Physics.Raycast(ray1, out hitInfo1,15))
|
|
{
|
|
|
|
if (hitInfo1.transform.gameObject.tag == "Wall")
|
|
{
|
|
wall = hitInfo1.transform.gameObject.transform;
|
|
return CarDriveStatu.减速;
|
|
}
|
|
|
|
|
|
if (hitInfo1.transform.gameObject.tag == "Car")
|
|
{
|
|
if (hitInfo1.transform.gameObject.GetComponent<Car>().isNormalDrive == false)
|
|
{
|
|
wall = hitInfo1.transform.gameObject.transform;
|
|
return CarDriveStatu.减速;
|
|
}
|
|
|
|
if (Vector3.Distance(this.transform.position, hitInfo1.transform.position) < 45)
|
|
{
|
|
return CarDriveStatu.怠速;
|
|
}
|
|
else if(Vector3.Distance(this.transform.position, hitInfo1.transform.position) < 30)
|
|
{
|
|
return CarDriveStatu.减速;
|
|
}
|
|
else if(Vector3.Distance(this.transform.position, hitInfo1.transform.position) > 45)
|
|
{
|
|
return CarDriveStatu.正常;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (driveStatu == CarDriveStatu.等红灯) return CarDriveStatu.等红灯;
|
|
//if (driveStatu == CarDriveStatu.怠速) return CarDriveStatu.怠速;
|
|
|
|
return CarDriveStatu.正常;
|
|
}
|
|
|
|
|
|
|
|
//侧翻事件
|
|
public void CeFan()
|
|
{
|
|
|
|
_Speed = Const.事故速度;
|
|
rig.velocity = Dir * _Speed;
|
|
isNormalDrive = false;
|
|
|
|
// this._Speed += 10f;
|
|
//transform.DOMoveZ(-1f, 2f);
|
|
// transform.DOMoveX(0.05f, 2f);
|
|
if (wayDir == WayDir.左侧)
|
|
{
|
|
transform.DORotate(new Vector3(0, 0, -80), 1.25f);
|
|
GameManagerForZhuanWan.Instance.LeftWall.SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
transform.DORotate(new Vector3(0, 0, -80), 1.25f);
|
|
GameManagerForZhuanWan.Instance.RightWall.SetActive(true);
|
|
}
|
|
//创建车的间隔减少
|
|
DriveManager.Instance.craetTime = 0.5f;
|
|
//提示事故
|
|
GameManagerForZhuanWan.Instance.actionTip.SetActive(true);
|
|
//移动镜头
|
|
GameManagerForZhuanWan.Instance.viewTheActionBtn.onClick.AddListener(() => {
|
|
float y = GameManagerForZhuanWan.Instance.pass1Camera.transform.position.y;
|
|
GameManagerForZhuanWan.Instance.pass1Camera.MoveToPoint(new Vector3(this.transform.position.x, y, this.transform.position.z), false);
|
|
});
|
|
|
|
//transform.DORotate(new Vector3(0, 0, -80), 1.25f);
|
|
GameManagerForZhuanWan.Instance.StartTimeAction(2f, () =>
|
|
{
|
|
this.rig.isKinematic = true;
|
|
BoxCollider collider = this.GetComponent<BoxCollider>();
|
|
collider.size = new Vector3(collider.size.x, 3f, collider.size.z);
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|