310 lines
9.1 KiB
C#
310 lines
9.1 KiB
C#
using DG.Tweening;
|
||
using Sirenix.OdinInspector;
|
||
using System.Collections;
|
||
using UnityEngine;
|
||
|
||
/// <summary>
|
||
/// NPCCar
|
||
/// </summary>
|
||
public class NPCCar : Car
|
||
{
|
||
/// <summary>
|
||
/// 自己在哪个索引
|
||
/// </summary>
|
||
public int index;
|
||
|
||
/// <summary>
|
||
/// 车皮肤索引
|
||
/// </summary>
|
||
private string skinCarIndex;
|
||
|
||
/// <summary>
|
||
/// 是否变道
|
||
/// </summary>
|
||
private bool isChangeLanes;
|
||
|
||
/// <summary>
|
||
/// 车节点
|
||
/// </summary>
|
||
public Transform carNode;
|
||
|
||
/// <summary>
|
||
/// 变道方向
|
||
/// </summary>
|
||
private E_DirectionType e_DirectionType;
|
||
|
||
/// <summary>
|
||
/// 路段
|
||
/// </summary>
|
||
private SectionRoad sectionRoad;
|
||
|
||
/// <summary>
|
||
/// 转向灯协程
|
||
/// </summary>
|
||
private Coroutine indicatorCoroutine;
|
||
|
||
private void OnEnable()
|
||
{
|
||
isChangeLanes = false;
|
||
rb.useGravity = false;
|
||
rb.isKinematic = true;
|
||
rb.velocity = Vector3.zero;
|
||
isDie = false;
|
||
if (indicatorCoroutine != null)
|
||
{
|
||
StopCoroutine(indicatorCoroutine);
|
||
indicatorCoroutine = null;
|
||
}
|
||
carNode.transform.DOKill();
|
||
carNode.transform.localEulerAngles = Vector3.zero;
|
||
}
|
||
|
||
private void Start()
|
||
{
|
||
Init();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化
|
||
/// </summary>
|
||
public void Init()
|
||
{
|
||
if(skinCarIndex==null)
|
||
{
|
||
skinCarIndex = "Car_" + Random.Range(1, 25);
|
||
}
|
||
skinCar = Instantiate(YooAssetManager.Instance.LoadAssetSync<GameObject>(PackagesName.GameData, skinCarIndex).GetComponent<SkinCar>());
|
||
skinCar.transform.SetParent(carNode);
|
||
skinCar.transform.localPosition = Vector3.zero;
|
||
skinCar.transform.localEulerAngles = Vector3.zero;
|
||
e_carSizeType = ConfigManager.Instance.GetE_CarSizeType(skinCarIndex);
|
||
SetColl();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置皮肤索引
|
||
/// </summary>
|
||
public void SetSkinCar(string car)
|
||
{
|
||
skinCarIndex = car;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置数据
|
||
/// </summary>
|
||
public void SetData(int index, SectionRoad sectionRoad)
|
||
{
|
||
this.index = index;
|
||
this.sectionRoad = sectionRoad;
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
ChangeLanes();
|
||
AllowRightWay();
|
||
Forward();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 变道
|
||
/// </summary>
|
||
private void ChangeLanes()
|
||
{
|
||
if (Vector3.Distance(Scenes.Instance.player.transform.position, this.transform.position) < 150 && !Scenes.Instance.player.isAmbulance && !Scenes.Instance.player.isSprint)
|
||
{
|
||
if (isChangeLanes)
|
||
{
|
||
if (IsObjectOnLeft(Scenes.Instance.player.gameObject,this.transform.gameObject))
|
||
{
|
||
if (this.index==sectionRoad.minIndex)
|
||
{
|
||
e_DirectionType = E_DirectionType.Right;
|
||
}
|
||
else
|
||
{
|
||
e_DirectionType = E_DirectionType.Left;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (this.index == sectionRoad.maxIndex)
|
||
{
|
||
e_DirectionType = E_DirectionType.Left;
|
||
}
|
||
else
|
||
{
|
||
e_DirectionType = E_DirectionType.Right;
|
||
}
|
||
}
|
||
Indicator(e_DirectionType, Scenes.Instance.gameScene.flashingLightNumber);
|
||
isChangeLanes = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
private bool IsObjectOnLeft(GameObject target, GameObject reference)
|
||
{
|
||
// 获取目标物体相对于参考物体的位置差
|
||
Vector3 directionToTarget = target.transform.position - reference.transform.position;
|
||
|
||
// 判断目标物体是否在参考物体的左边
|
||
// 使用参考物体的右方向(transform.right)
|
||
float dotProduct = Vector3.Dot(reference.transform.right, directionToTarget);
|
||
|
||
// 如果点积为负,表示目标物体在参考物体的左边
|
||
return dotProduct < 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 向前行驶
|
||
/// </summary>
|
||
private void Forward()
|
||
{
|
||
if (Vector3.Distance(Scenes.Instance.player.transform.position, this.transform.position) < 150)
|
||
{
|
||
transform.Translate(transform.forward * Time.deltaTime * 15, Space.World);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 让道
|
||
/// </summary>
|
||
private void AllowRightWay()
|
||
{
|
||
if (Scenes.Instance.player.isAmbulance && Vector3.Distance(Scenes.Instance.player.transform.position, this.transform.position) < 150)
|
||
{
|
||
if (indicatorCoroutine != null)
|
||
{
|
||
StopCoroutine(indicatorCoroutine);
|
||
skinCar.SetAllLight(false);
|
||
}
|
||
if (this.index == Scenes.Instance.player.moveIndex)
|
||
{
|
||
if (ProbabilityManager.Instance.GetPercent(50))
|
||
{
|
||
if (this.index > sectionRoad.minIndex)
|
||
{
|
||
ChangeLanes(E_DirectionType.Left, 0.2f);
|
||
}
|
||
else
|
||
{
|
||
ChangeLanes(E_DirectionType.Right, 0.2f);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (this.index < sectionRoad.maxIndex)
|
||
{
|
||
ChangeLanes(E_DirectionType.Right, 0.2f);
|
||
}
|
||
else
|
||
{
|
||
ChangeLanes(E_DirectionType.Left, 0.2f);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 击飞
|
||
/// </summary>
|
||
public void ShootFly(Transform transform)
|
||
{
|
||
if (isDie) return;
|
||
rb.useGravity = true;
|
||
rb.isKinematic = false;
|
||
rb.AddForce((transform.position - this.transform.position).normalized * -100, ForceMode.Impulse);
|
||
rb.AddForce(Vector3.up * 20, ForceMode.Impulse);
|
||
rb.AddTorque(new Vector3(Random.Range(-180, 180), Random.Range(-180, 180), Random.Range(-180, 180)), ForceMode.Impulse);
|
||
isDie = true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置向左还是右
|
||
/// </summary>
|
||
public void ISChangeLanes()
|
||
{
|
||
this.isChangeLanes = true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置向左还是右
|
||
/// </summary>
|
||
public void SetRightLeft(E_DirectionType e_DirectionType)
|
||
{
|
||
this.isChangeLanes = true;
|
||
this.e_DirectionType = e_DirectionType;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 转向灯
|
||
/// </summary>
|
||
private void Indicator(E_DirectionType e_DirectionType, float number)
|
||
{
|
||
indicatorCoroutine = StartCoroutine(IE_Indicator(e_DirectionType, number));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 转向灯协程
|
||
/// </summary>
|
||
protected IEnumerator IE_Indicator(E_DirectionType e_DirectionType, float number)
|
||
{
|
||
for (int i = 0; i < Mathf.RoundToInt(number); i++)
|
||
{
|
||
switch (e_DirectionType)
|
||
{
|
||
case E_DirectionType.Left:
|
||
skinCar.leftQueenIndicator.gameObject.SetActive(true);
|
||
yield return new WaitForSeconds(0.1f);
|
||
skinCar.leftQueenIndicator.gameObject.SetActive(false);
|
||
yield return new WaitForSeconds(0.1f);
|
||
break;
|
||
case E_DirectionType.Right:
|
||
skinCar.rightQueenIndicator.gameObject.SetActive(true);
|
||
yield return new WaitForSeconds(0.1f);
|
||
skinCar.rightQueenIndicator.gameObject.SetActive(false);
|
||
yield return new WaitForSeconds(0.1f);
|
||
break;
|
||
}
|
||
yield return null;
|
||
}
|
||
ChangeLanes(e_DirectionType, Scenes.Instance.gameScene.npcLaneChangeSpeed);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 变道
|
||
/// </summary>
|
||
public override void ChangeLanes(E_DirectionType e_DirectionType, float speed)
|
||
{
|
||
float recordLaneChangeDistance = 0;
|
||
float yaw = 0;//摆头
|
||
switch (e_DirectionType)
|
||
{
|
||
case E_DirectionType.Left:
|
||
index--;
|
||
recordLaneChangeDistance = -laneChangeDistance;
|
||
yaw = -20;
|
||
break;
|
||
case E_DirectionType.Right:
|
||
index++;
|
||
recordLaneChangeDistance = laneChangeDistance;
|
||
yaw = 20;
|
||
break;
|
||
}
|
||
this.transform.DOKill();
|
||
if (this.transform.parent == null)
|
||
{
|
||
this.transform.DOMoveZ(this.transform.position.z - recordLaneChangeDistance, speed);
|
||
}
|
||
else
|
||
{
|
||
this.transform.DOLocalMoveX(this.transform.localPosition.x + recordLaneChangeDistance, speed);
|
||
}
|
||
carNode.transform.DOLocalRotate(new Vector3(0, yaw, 0), speed).OnComplete(() =>
|
||
{
|
||
carNode.transform.DOLocalRotate(new Vector3(0, 0, 0), speed);
|
||
});
|
||
}
|
||
}
|