OvertakingLegend/Assets/Script/NPCCar.cs

310 lines
9.1 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
});
}
}