613 lines
23 KiB
C#
613 lines
23 KiB
C#
using EVP;
|
||
using Script.Manaegr;
|
||
using UnityEngine;
|
||
using UnityEngine.UIElements;
|
||
using Button = UnityEngine.UI.Button;
|
||
|
||
namespace Script
|
||
{
|
||
using ModbusManager;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Threading.Tasks;
|
||
using Unity.VisualScripting;
|
||
using UnityEngine;
|
||
|
||
public class CarGearControl : MonoBehaviour
|
||
{
|
||
public GameObject ui3d;
|
||
public GameObject ui2d;
|
||
|
||
|
||
private VehicleController vehicleController;
|
||
|
||
private VehicleStandardInput vehicleStandardInput;
|
||
|
||
public int currentGear = 0; // 当前挡位
|
||
|
||
//public float[] gearSpeeds = { 0f, 20f, 40f, 60f }; // 每个挡位的最大速度
|
||
public List<float> gearSpeeds; // 每个挡位的最大速度
|
||
|
||
public float xx;
|
||
float steerInput, throttleInput, brakeInput, handbrakeInput;
|
||
|
||
private CarStatusData carData;
|
||
|
||
float minValue = -700f; // 范围的最小值
|
||
float maxValue = 700; // 范围的最大值
|
||
|
||
public CarInfoManager carInfoManager;
|
||
private ModbusTcpClient client;
|
||
private int NewValue = -1;
|
||
|
||
|
||
public GameObject thirdPerson; //第三人称
|
||
public GameObject firstPerson; //第一人称
|
||
|
||
|
||
public GameObject[] shache;
|
||
|
||
public AnimationController ygq;
|
||
public TurnSignalController turnSignalController;
|
||
|
||
private bool inputUp = false;
|
||
private int inputUpV = -1;
|
||
|
||
public GameObject uiGame;
|
||
|
||
public GameObject carMenuUI;
|
||
|
||
public GameObject accident; //事故UI
|
||
public GameObject honglvdengUI; //事故UI public GameObject accident; //事故UI
|
||
private bool ClutchPedalPositionBool;
|
||
|
||
|
||
public bool mingdi = false;
|
||
public AccidentManager accidentManager;
|
||
|
||
public Transform ttt;
|
||
|
||
private bool dianhuo = false;
|
||
|
||
private Coroutine currentCoroutine = null; // 当前正在运行的协程
|
||
private int lastEndIndex = 0; // 上一次的结束索引
|
||
private int currentEndIndex = 0; // 当前的结束索引
|
||
|
||
public bool isShache = false;
|
||
|
||
public void LoadData()
|
||
{
|
||
gearSpeeds = new List<float>();
|
||
int originalCount = 21;
|
||
int targetCount = 100;
|
||
int interval = (targetCount - 1) / (originalCount - 1);
|
||
|
||
for (int i = 1; i <= originalCount; i++)
|
||
{
|
||
float startValue = i;
|
||
gearSpeeds.Add(startValue);
|
||
|
||
if (i < originalCount)
|
||
{
|
||
float endValue = i + 1;
|
||
for (int j = 1; j < interval; j++)
|
||
{
|
||
float interpolatedValue = startValue + (endValue - startValue) * j / interval;
|
||
gearSpeeds.Add(interpolatedValue);
|
||
}
|
||
}
|
||
}
|
||
|
||
gearSpeeds[0] = 0;
|
||
gearSpeeds[1] = 0;
|
||
gearSpeeds[2] = 0;
|
||
gearSpeeds[3] = 0;
|
||
gearSpeeds[4] = 0;
|
||
gearSpeeds[5] = 0;
|
||
gearSpeeds[6] = 0;
|
||
gearSpeeds[7] = 0;
|
||
gearSpeeds[8] = 0;
|
||
gearSpeeds[9] = 0;
|
||
gearSpeeds[10] = 0;
|
||
}
|
||
|
||
|
||
void Start()
|
||
{
|
||
LoadData();
|
||
|
||
vehicleController = GetComponent<VehicleController>();
|
||
vehicleStandardInput = GetComponent<VehicleStandardInput>();
|
||
|
||
StartModbus();
|
||
ModBusQueue();
|
||
}
|
||
|
||
async Task StartModbus()
|
||
{
|
||
client = new ModbusTcpClient();
|
||
if (await client.ConnectToServer())
|
||
{
|
||
Debug.Log("连接上");
|
||
}
|
||
else
|
||
{
|
||
this.GetComponent<CarGearControl>().enabled = false;
|
||
this.GetComponent<VehicleStandardInput>().enabled = true;
|
||
this.GetComponent<CarInputManager>().enabled = true;
|
||
this.GetComponent<CarInputManager>().Init();
|
||
Debug.Log("断开连接");
|
||
}
|
||
|
||
|
||
// client.StartModbus();
|
||
|
||
while (true)
|
||
{
|
||
await client.SendModbusRequest();
|
||
|
||
await Task.Delay(TimeSpan.FromSeconds(.1));
|
||
}
|
||
}
|
||
|
||
|
||
public void HHHHHH()
|
||
{
|
||
client.SendModbusRequest12();
|
||
}
|
||
|
||
void OnDestroy()
|
||
{
|
||
client.CloseConnection();
|
||
}
|
||
|
||
async Task ModBusQueue()
|
||
{
|
||
while (true)
|
||
{
|
||
try
|
||
{
|
||
// Debug.Log(client.modbusQueue.Count);
|
||
if (client.modbusQueue.Count > 0)
|
||
{
|
||
// Debug.Log(client.modbusQueue.Count);
|
||
|
||
carData = client.modbusQueue.Dequeue();
|
||
|
||
|
||
// if (ModbusTcpClient.modbusTcpClient.modbusQueue.Count > 0)
|
||
// {
|
||
// // Debug.Log(ModbusTcpClient.modbusTcpClient.modbusQueue.Count);
|
||
//
|
||
// carData = ModbusTcpClient.modbusTcpClient.modbusQueue.Dequeue();
|
||
|
||
|
||
//方向盘
|
||
vehicleController.steerInput = NormalizeValue(carData.SteeringWheelAngle, minValue, maxValue);
|
||
|
||
|
||
//钥匙 00是熄火,1是通电,2是点火
|
||
switch (carData.KeyStatus)
|
||
{
|
||
case 0:
|
||
uiGame.SetActive(false);
|
||
break;
|
||
case 1:
|
||
break;
|
||
case 2:
|
||
if (carData.BrakePedalPosition > 30)
|
||
{
|
||
uiGame.SetActive(true);
|
||
currentGear = 0;
|
||
dianhuo = true;
|
||
ui2d.SetActive(true);
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
if (!dianhuo)
|
||
continue;
|
||
|
||
//手刹
|
||
// vehicleController.throttleInput = carData.HandbrakeStatus == 0 ? 1 : 0;
|
||
//挡位 00空挡,1前进档,2倒挡,3为P档
|
||
//当钥匙为点火状态,才能启动车
|
||
if (carData.IgnitionSwitch == 1)
|
||
{
|
||
switch (carData.GearPosition)
|
||
{
|
||
case 0:
|
||
vehicleController.throttleInput = 0;
|
||
currentGear = 0;
|
||
break;
|
||
case 1: //1前进档
|
||
if (carData.HandbrakeStatus == 0)
|
||
{
|
||
//if (carData.AcceleratorPedalPosition > 20 && carData.AcceleratorPedalPosition <= 50)
|
||
//{
|
||
// vehicleController.throttleInput = 1;
|
||
// currentGear = 1;
|
||
//}
|
||
//else if (carData.AcceleratorPedalPosition > 50 && carData.AcceleratorPedalPosition <= 80)
|
||
//{
|
||
// vehicleController.throttleInput = 1;
|
||
// currentGear = 2;
|
||
//}
|
||
//else if (carData.AcceleratorPedalPosition > 80 && carData.AcceleratorPedalPosition <= 100)
|
||
//{
|
||
// vehicleController.throttleInput = 1;
|
||
// currentGear = 3;
|
||
//}
|
||
//else
|
||
//{
|
||
// vehicleController.throttleInput = 0;
|
||
// currentGear = 0;
|
||
//}
|
||
|
||
|
||
if (carData.AcceleratorPedalPosition < 10)
|
||
{
|
||
vehicleController.throttleInput = 0;
|
||
currentGear = 0;
|
||
}
|
||
else
|
||
{
|
||
vehicleController.throttleInput = 1;
|
||
currentGear = carData.AcceleratorPedalPosition;
|
||
currentEndIndex = currentGear;
|
||
|
||
if (currentEndIndex != lastEndIndex)
|
||
{
|
||
float totalDuration = currentEndIndex < lastEndIndex ? 5.0f : 2.0f;
|
||
StartRetrieveData(lastEndIndex, currentEndIndex, totalDuration);
|
||
lastEndIndex = currentEndIndex;
|
||
}
|
||
}
|
||
|
||
//当转向没有打灯就弹窗
|
||
if (carData.SteeringWheelAngle > 200)
|
||
{
|
||
if (turnSignalController.turnSignalState != TurnSignalState.右转向)
|
||
{
|
||
accidentManager.PlayAnimationSequence("MsgWinAnimOpen", "MsgWinAnimClose");
|
||
accidentManager.uis.transform.Find("UI/转向").gameObject.SetActive(true);
|
||
}
|
||
}
|
||
else if (carData.SteeringWheelAngle < -200)
|
||
{
|
||
if (turnSignalController.turnSignalState != TurnSignalState.左转向)
|
||
{
|
||
accidentManager.PlayAnimationSequence("MsgWinAnimOpen", "MsgWinAnimClose");
|
||
accidentManager.uis.transform.Find("UI/转向").gameObject.SetActive(true);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
vehicleController.throttleInput = 0;
|
||
}
|
||
|
||
break;
|
||
case 2: //2倒挡
|
||
if (carData.HandbrakeStatus == 0)
|
||
{
|
||
if (carData.AcceleratorPedalPosition > 20)
|
||
{
|
||
vehicleController.throttleInput = -0.5f;
|
||
}
|
||
else
|
||
{
|
||
vehicleController.throttleInput = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
vehicleController.throttleInput = 0;
|
||
}
|
||
|
||
break;
|
||
case 3:
|
||
break;
|
||
}
|
||
}
|
||
|
||
//转向灯 00是未开转向灯,1是左转向灯,2是右转向灯
|
||
//当钥匙转为通电才能启动转向灯 0熄火,1通电,2启动
|
||
// if (carData.IgnitionSwitch == 1)
|
||
// {
|
||
// switch (carData.TurnSignalStatus)
|
||
// {
|
||
// case 0:
|
||
// carInfoManager.StopBlinking();
|
||
// break;
|
||
// case 1:
|
||
// carInfoManager.LeftStartBlinking();
|
||
// break;
|
||
// case 2:
|
||
// carInfoManager.RightStartBlinking();
|
||
// break;
|
||
// }
|
||
// }
|
||
|
||
|
||
//上1,右2,下3,左4
|
||
if (NewValue != carData.ButtonData)
|
||
{
|
||
NewValue = carData.ButtonData;
|
||
CarMenuButton(NewValue);
|
||
}
|
||
// else
|
||
// {
|
||
// continue;
|
||
// }
|
||
|
||
//雨刮器
|
||
if (carData.WiperStatus == 2)
|
||
{
|
||
ygq.PlayAnimation("donghua");
|
||
}
|
||
else
|
||
{
|
||
ygq.StopAnimationLoop();
|
||
}
|
||
|
||
|
||
if (mingdi)
|
||
{
|
||
if (carData.HornStatus == 1)
|
||
{
|
||
mingdi = false;
|
||
accidentManager.Tr(ttt, true);
|
||
}
|
||
}
|
||
|
||
//转向灯和双闪
|
||
if (carData.ButtonData == 1)
|
||
{
|
||
if (!inputUp)
|
||
{
|
||
inputUp = true;
|
||
inputUpV = carData.TurnSignalStatus;
|
||
}
|
||
else
|
||
{
|
||
inputUp = false;
|
||
inputUpV = -1;
|
||
turnSignalController.rightTurnSignalGame.SetActive(false);
|
||
turnSignalController.leftTurnSignalGame.SetActive(false);
|
||
turnSignalController.SetSignal(0);
|
||
}
|
||
}
|
||
|
||
if (inputUpV == carData.TurnSignalStatus)
|
||
{
|
||
turnSignalController.SetSignal(3);
|
||
}
|
||
else
|
||
{
|
||
inputUpV = -1;
|
||
switch (carData.TurnSignalStatus)
|
||
{
|
||
case 0:
|
||
turnSignalController.SetSignal(0);
|
||
break;
|
||
case 1:
|
||
turnSignalController.SetSignal(1);
|
||
break;
|
||
case 2:
|
||
turnSignalController.SetSignal(2);
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
// 灯光
|
||
switch (carData.LightStatus)
|
||
{
|
||
case 0:
|
||
turnSignalController.CloseLight();
|
||
break;
|
||
case 1:
|
||
turnSignalController.OpenLight();
|
||
break;
|
||
case 2:
|
||
|
||
break;
|
||
}
|
||
|
||
|
||
// if (honglvdengUI.activeInHierarchy)
|
||
// {
|
||
// if (carData.AcceleratorPedalPosition > 90)
|
||
// {
|
||
// honglvdengUI.transform.Find("重置").GetComponent<Button>().onClick.Invoke();
|
||
// }
|
||
// }
|
||
|
||
|
||
// if (accident.activeInHierarchy)
|
||
// {
|
||
// if (carData.AcceleratorPedalPosition > 90)
|
||
// {
|
||
// accident.transform.Find("重置").GetComponent<Button>().onClick.Invoke();
|
||
// }
|
||
// }
|
||
// else
|
||
// {
|
||
|
||
//踩离合弹出菜单UI
|
||
if (carData.ClutchPedalPosition > 30)
|
||
{
|
||
if (!ClutchPedalPositionBool)
|
||
{
|
||
ClutchPedalPositionBool = true;
|
||
carMenuUI.SetActive(true);
|
||
}
|
||
}
|
||
else if (carData.ClutchPedalPosition <= 0)
|
||
{
|
||
ClutchPedalPositionBool = false;
|
||
}
|
||
|
||
if (carMenuUI.activeInHierarchy)
|
||
{
|
||
if (carData.ButtonData == 4)
|
||
{
|
||
carMenuUI.GetComponent<CarMenuManager>().Back();
|
||
}
|
||
else if (carData.ButtonData == 2)
|
||
{
|
||
carMenuUI.GetComponent<CarMenuManager>().Next();
|
||
}
|
||
|
||
if (carData.AcceleratorPedalPosition > 30)
|
||
{
|
||
carMenuUI.GetComponent<CarMenuManager>().Click();
|
||
}
|
||
}
|
||
// }
|
||
|
||
//刹车
|
||
if (carData.BrakePedalPosition > 30)
|
||
{
|
||
if (shache[0].activeInHierarchy)
|
||
continue;
|
||
|
||
isShache = true;
|
||
for (int i = 0; i < shache.Length; i++)
|
||
{
|
||
shache[i].SetActive(true);
|
||
}
|
||
|
||
vehicleController.throttleInput = 0;
|
||
currentGear = 0;
|
||
}
|
||
else
|
||
{
|
||
isShache = false;
|
||
if (!shache[0].activeInHierarchy)
|
||
continue;
|
||
for (int i = 0; i < shache.Length; i++)
|
||
{
|
||
shache[i].SetActive(false);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
// Console.WriteLine(e);
|
||
// throw;
|
||
}
|
||
|
||
await Task.Delay(TimeSpan.FromSeconds(.1));
|
||
}
|
||
}
|
||
|
||
public void StartRetrieveData(int startIndex, int endIndex, float totalDuration)
|
||
{
|
||
if (currentCoroutine != null)
|
||
{
|
||
StopCoroutine(currentCoroutine);
|
||
}
|
||
|
||
// 跳过前三个元素
|
||
startIndex = Mathf.Max(startIndex, 3);
|
||
|
||
currentCoroutine = StartCoroutine(RetrieveData(startIndex, endIndex, totalDuration));
|
||
}
|
||
|
||
IEnumerator RetrieveData(int startIndex, int endIndex, float totalDuration)
|
||
{
|
||
// 确定遍历方向
|
||
int step = startIndex < endIndex ? 1 : -1;
|
||
int count = Mathf.Abs(endIndex - startIndex) + 1;
|
||
float delay = totalDuration / count;
|
||
|
||
for (int i = startIndex; step > 0 ? i <= endIndex : i >= endIndex; i += step)
|
||
{
|
||
yield return new WaitForSeconds(delay);
|
||
}
|
||
|
||
currentCoroutine = null;
|
||
}
|
||
|
||
void CarMenuButton(int bt)
|
||
{
|
||
if (bt == 3)
|
||
{
|
||
if (thirdPerson.activeInHierarchy)
|
||
{
|
||
thirdPerson.SetActive(false);
|
||
firstPerson.SetActive(true);
|
||
|
||
ui3d.SetActive(true);
|
||
ui2d.SetActive(false);
|
||
}
|
||
else
|
||
{
|
||
thirdPerson.SetActive(true);
|
||
firstPerson.SetActive(false);
|
||
|
||
|
||
ui3d.SetActive(false);
|
||
ui2d.SetActive(true);
|
||
}
|
||
}
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
// 检测并更新挡位
|
||
CheckAndUpdateGear();
|
||
|
||
// 根据当前挡位设置车辆速度
|
||
SetVehicleSpeed(gearSpeeds[currentGear]);
|
||
|
||
//vehicleController.steerInput = 0;
|
||
|
||
// vehicleController.brakeInput = 0;
|
||
// vehicleController.handbrakeInput = 0;
|
||
//Debug.Log($"{steerInput}--{throttleInput}--{brakeInput}--{handbrakeInput}");
|
||
|
||
// vehicleStandardInput.SetThrottleValue(xx);
|
||
|
||
// SetSpeedBasedOnValue(1);
|
||
|
||
|
||
if (Input.GetKeyDown(KeyCode.F12))
|
||
{
|
||
client.SendModbusRequest();
|
||
}
|
||
}
|
||
|
||
void CheckAndUpdateGear()
|
||
{
|
||
if (Input.GetKeyDown(KeyCode.Alpha1)) currentGear = 1;
|
||
if (Input.GetKeyDown(KeyCode.Alpha2)) currentGear = 2;
|
||
if (Input.GetKeyDown(KeyCode.Alpha3)) currentGear = 3;
|
||
if (Input.GetKeyDown(KeyCode.Alpha0)) currentGear = 0; // 假设0为空挡
|
||
}
|
||
|
||
void SetVehicleSpeed(float maxSpeed)
|
||
{
|
||
// 在这里,你需要根据你的车辆控制系统来调整速度。
|
||
// 以下是一个假设的方法,你可能需要根据EVP5的API来修改它。
|
||
vehicleController.maxSpeedForward = maxSpeed;
|
||
//vehicleController.throttleInput = 1;
|
||
}
|
||
|
||
public float NormalizeValue(float originalValue, float minValue, float maxValue)
|
||
{
|
||
// 确保原始值在范围内
|
||
float clampedValue = Math.Max(minValue, Math.Min(originalValue, maxValue));
|
||
|
||
// 计算归一化值
|
||
float normalizedValue = (2 * (clampedValue - minValue) / (maxValue - minValue)) - 1;
|
||
|
||
return normalizedValue;
|
||
}
|
||
}
|
||
} |