using DG.Tweening; using Sirenix.OdinInspector; using System.Collections; using UnityEngine; /// /// NPCCar /// public class NPCCar : Car { /// /// 自己在哪个索引 /// public int index; /// /// 车皮肤索引 /// private string skinCarIndex; /// /// 是否变道 /// private bool isChangeLanes; /// /// 车节点 /// public Transform carNode; /// /// 变道方向 /// private E_DirectionType e_DirectionType; /// /// 路段 /// private SectionRoad sectionRoad; /// /// 转向灯协程 /// 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(); } /// /// 初始化 /// public void Init() { if(skinCarIndex==null) { skinCarIndex = "Car_" + Random.Range(1, 25); } skinCar = Instantiate(YooAssetManager.Instance.LoadAssetSync(PackagesName.GameData, skinCarIndex).GetComponent()); skinCar.transform.SetParent(carNode); skinCar.transform.localPosition = Vector3.zero; skinCar.transform.localEulerAngles = Vector3.zero; e_carSizeType = ConfigManager.Instance.GetE_CarSizeType(skinCarIndex); SetColl(); } /// /// 设置皮肤索引 /// public void SetSkinCar(string car) { skinCarIndex = car; } /// /// 设置数据 /// public void SetData(int index, SectionRoad sectionRoad) { this.index = index; this.sectionRoad = sectionRoad; } private void Update() { ChangeLanes(); AllowRightWay(); Forward(); } /// /// 变道 /// 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; } /// /// 向前行驶 /// private void Forward() { if (Vector3.Distance(Scenes.Instance.player.transform.position, this.transform.position) < 150) { transform.Translate(transform.forward * Time.deltaTime * 15, Space.World); } } /// /// 让道 /// 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); } } } } } /// /// 击飞 /// 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; } /// /// 设置向左还是右 /// public void ISChangeLanes() { this.isChangeLanes = true; } /// /// 设置向左还是右 /// public void SetRightLeft(E_DirectionType e_DirectionType) { this.isChangeLanes = true; this.e_DirectionType = e_DirectionType; } /// /// 转向灯 /// private void Indicator(E_DirectionType e_DirectionType, float number) { indicatorCoroutine = StartCoroutine(IE_Indicator(e_DirectionType, number)); } /// /// 转向灯协程 /// 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); } /// /// 变道 /// 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); }); } }