1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > java模拟汽车驾驶场景_Unity平台模拟自动挡驾驶汽车

java模拟汽车驾驶场景_Unity平台模拟自动挡驾驶汽车

时间:2023-03-30 10:23:14

相关推荐

java模拟汽车驾驶场景_Unity平台模拟自动挡驾驶汽车

自动挡汽车功能分析:

(1)刹车数值用连续量0-255表示,连续量根据键盘按键按下时长进行递增,1秒后达到峰值,无论车辆处于前进挡还是倒挡,踩下刹车后车辆逐渐减速至0

(2)汽车分为四个挡位,停车挡P,倒挡R,空挡N,前进挡D

(3)汽车启动后,松开刹车,车辆进入怠速模式,速度从0逐步提升至12KM/H

(4)刹车数值用连续量0-255表示。车速对应1档0-10,2档11-20,3档21-40,4档41-60,5档61-80,6档81-最大值,对应峰值车速150KM/H

(5)挂住P档,拉起手刹车辆停止。

(6)挂住R档,车辆可进行倒车操作。

(7)通过键盘A和D可以控制车辆左右转向

运行结果图:

启动车辆,拉起手刹,挂前进挡,车辆进入怠速模式,缓慢进行加速。

速度提升到12km/h后匀速行驶,继续加速需要踩下油门。

踩下油门后车辆快速加速,自行切换挡位:

前进时踩下刹车后车子逐渐减速至0:

切换至倒挡,踩下油门,车辆后退,踩下刹车,车子逐渐减速至0:

前进时左右转向:

倒挡时左右转型:

源代码:

采用manager of manager的方式,使用了单例模式。

1.Car_Mng类负责管理车辆的物理仿真

2.Input_Mng类负责接受用户的键盘输入信息

3.UI_Mng类负责更新UI界面的显示

Car_Mng

using System.Collections;

using System.Collections.Generic;

using System.Diagnostics.Tracing;

using UnityEngine;

public class Car_Mng : MonoBehaviour

{

static public Car_Mng Instance;

public SpeedGear speedGear;

public float maxMotorTorque; //最大的前进力矩

public float maxSpeed; //车辆最大前进速度

public float maxReversMotorTorque; //最大的倒车力矩

public float maxBrakeToeque; //最大的刹车阻力

public float maxSteeringAngle; //主动轮最大的旋转角度

public Rigidbody car; //车辆的刚体

public WheelCollider[] coliders; //车轮碰撞器

public GameObject[] wheelMesh; //车轮模型

public CarState carState=CarState.Off; //车辆启动状态

public GearState gearState = GearState.ParkingGear; //车辆的挡位

public bool isHandBrakeON; //是否拉起手刹的标志位

public float currentSpeed=0; //计算当前车辆的速度

private bool currentHandBrakeState=true;

private void Awake()

{

Instance = this;

}

void Start()

{

/* coliders[0].steerAngle = 30;

coliders[1].steerAngle = 30;

for (int i = 0; i < 4; i++)

{

Quaternion quat;

Vector3 position;

coliders[i].GetWorldPose(out position, out quat);

Debug.Log(position);

Debug.Log(quat.eulerAngles);

wheelMesh[i].transform.position = position;

wheelMesh[i].transform.rotation =

coliders[i].transform.rotation * Quaternion.Euler(0, coliders[i].steerAngle, 0);

}*/

}

private void Update()

{

UpdateHandBrokeState(); //更新手刹状态

}

private void FixedUpdate()

{

if (gearState == GearState.ForwardGear || gearState == GearState.ReversGear)

{

BrakeCalculate(); //刹车计算 阻力

AccCalculate(); //油门计算 动力

}

SteerCalculate();

UpdateCarSpeed(); //更新车子的速度

AutoChangeGear(); //自动换挡 自动挡的车子

SynchronousWheelMesh(); //将车轮的状态同步给车的模型

}

void SynchronousWheelMesh()

{

for (int i = 0; i < 6; i++)

{

Quaternion quat;

Vector3 position;

coliders[i].GetWorldPose(out position, out quat);

wheelMesh[i].transform.position = position;

wheelMesh[i].transform.rotation = quat;

}

}

void UpdateHandBrokeState()

{

if (currentHandBrakeState != isHandBrakeON)

{

currentHandBrakeState = isHandBrakeON;

if (currentHandBrakeState)

{

PullupHandbrake();

}

else

{

PullDownHandbrake();

}

}

} //更新手刹状态

public void StartCar() //启动车辆

{

carState = CarState.On;

}

public void StopCar() //停车

{

carState = CarState.Off; //停止接收油门、方向盘、刹车信号

gearState = GearState.ParkingGear; //挂上停车挡

PullupHandbrake(); //拉起手刹

}

void PullupHandbrake() //拉起手刹,相当于阻力矩最大,直接Freeze车辆刚体的运动

{

isHandBrakeON = true; //设置标志位

//仅保留y轴向的运动

car.constraints = RigidbodyConstraints.FreezeRotation

| RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezePositionZ;

}

void PullDownHandbrake() //放下手刹,解锁运动

{

isHandBrakeON = false;

//解锁所有运动

car.constraints = RigidbodyConstraints.None;

}

void BrakeCalculate() //计算刹车的阻力

{

var value = Input_Mng.Instance.GetBrakeValue(); //读取刹车阻力

var brakeToequePerWheel = maxBrakeToeque / 2 * value / 255; //计算一个车轮的阻力

coliders[0].motorTorque = 0;

coliders[1].motorTorque = 0;

for (int i = 0; i < 6; i++)

{

coliders[i].brakeTorque = brakeToequePerWheel;

}

// Debug.Log("刹车阻力:"+ brakeToequePerWheel);

}

void AccCalculate() //油门动力计算

{

if (gearState == GearState.ForwardGear) //前进

{

var value = Input_Mng.Instance.GetAcceleratorValue();

if (value != 0) //加速行驶

{

if(MeterPerSeconds2KmPerHour(currentSpeed) <= 150)

{

var accToequePerWheel = maxMotorTorque * value / 255; //计算一个车轮的动力

coliders[0].motorTorque = accToequePerWheel;

coliders[1].motorTorque = accToequePerWheel;

}

else //不能超过速度上限

{

coliders[0].motorTorque = 0;

coliders[1].motorTorque = 0;

}

}

else //怠速驾驶

{

if (MeterPerSeconds2KmPerHour(currentSpeed) < 12)

{

coliders[0].motorTorque = 100;

coliders[1].motorTorque = 100;

}

else

{

Debug.Log("无动力");

for (int i = 0; i < 6; i++)

{

coliders[i].motorTorque = 0;

}

}

}

}

else //倒车

{

var value = Input_Mng.Instance.GetAcceleratorValue();

var accToequePerWheel = maxReversMotorTorque / 2 * value / 255; //计算一个车轮的动力

coliders[0].motorTorque = -accToequePerWheel;

coliders[1].motorTorque = -accToequePerWheel;

}

}

void SteerCalculate() //计算转向

{

var value= Input_Mng.Instance.GetSteerValue();

var steerAngle = (value - 128) / 128 * maxSteeringAngle; //计算旋转角度

coliders[0].steerAngle = steerAngle;

coliders[1].steerAngle = steerAngle;

}

void AutoChangeGear() //自动挡,前进时根据车辆的速度自动切换挡位

{

if (gearState == GearState.ForwardGear)

{

var speed = MeterPerSeconds2KmPerHour(currentSpeed);

if (speed <= 10 && speed > 0)

{

speedGear = SpeedGear.Speed01;

}

if (speed <= 20 && speed > 10)

{

speedGear = SpeedGear.Speed02;

}

if (speed <= 40 && speed > 20)

{

speedGear = SpeedGear.Speed03;

}

if (speed <= 60 && speed > 40)

{

speedGear = SpeedGear.Speed04;

}

if (speed <= 80 && speed > 60)

{

speedGear = SpeedGear.Speed05;

}

if (speed <= 155 && speed > 80)

{

speedGear = SpeedGear.Speed06;

}

}

else

{

speedGear = SpeedGear.none;

}

}

void UpdateCarSpeed()

{

currentSpeed = car.velocity.magnitude;

}

static public float MeterPerSeconds2KmPerHour(float speed) //切换单位 m/s换算成 km/h

{

return speed*3.6f;

}

static float KmPerHour2MeterPerSeconds(float speed) //切换单位 km/h换算成m/s

{

return speed/3.6f;

}

}

public enum CarState

{

Off = 0, //关机状态

On = 1, //运行状态

}

public enum GearState

{

ParkingGear = 1, //停车挡

ReversGear = 2, //倒挡

NeutralGear = 3, //空挡

ForwardGear = 4, //前进挡

}

public enum SpeedGear

{

none,

Speed01,

Speed02,

Speed03,

Speed04,

Speed05,

Speed06

}

Input_Mng

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class Input_Mng : MonoBehaviour

{

static public Input_Mng Instance; //单例模式

private KeyCode braKeyCode=KeyCode.M; //刹车对应的键盘按键

public float brakeValue = 0; //刹车值

public bool isBra = false;

private KeyCode accKeyCode=KeyCode.W; //油门对应的键盘按键

public float acceleratorValue = 0; //油门值

public bool isAcc = false;

private KeyCode leftSteerKeyCode = KeyCode.A;

private KeyCode rightSteerKeyCode = KeyCode.D;

public float steerValue = 128;

private KeyCode parkingKeyCode = KeyCode.Alpha1; //停车对应的按键

private KeyCode reversKeyCode = KeyCode.Alpha2; //倒车对应的按键

private KeyCode neutralKeyCode = KeyCode.Alpha3; //空挡对应的按键

private KeyCode forwardKeyCode = KeyCode.Alpha4; //前进挡对应的按键

private KeyCode handBrakeKeyCode = KeyCode.H; //手刹对应的按键

public float GetBrakeValue() //获取刹车值

{

return brakeValue;

}

public float GetAcceleratorValue() //获取油门值

{

return acceleratorValue;

}

public float GetSteerValue()

{

return steerValue;

} //获取转弯值

private void Awake()

{

Instance = this;

}

private void Update()

{

if (Car_Mng.Instance.carState == CarState.On) //当车辆启动后,检测油门刹车和挡位变换

{

UpdateGeerState();

}

UpdateSteerValue();

UpdateHandBrakeState();

UpdateAcceleratorValue(accKeyCode);

UpdateBrakeValue(braKeyCode);

}

void UpdateHandBrakeState()

{

if (Input.GetKeyDown(handBrakeKeyCode))

{

if (Car_Mng.Instance.isHandBrakeON)

{

Car_Mng.Instance.isHandBrakeON = false;

}

else

{

Car_Mng.Instance.isHandBrakeON = true;

}

}

}

void UpdateAcceleratorValue(KeyCode AccCode)

{

if (Input.GetKey(AccCode))

{

acceleratorValue += 255 * Time.deltaTime;

acceleratorValue = Mathf.Clamp(acceleratorValue, 0, 255);

isAcc = true;

}

else

{

acceleratorValue = 0;

isAcc = false;

}

} //更新油门状态

void UpdateBrakeValue(KeyCode BraCode) //更新刹车状态

{

if (Input.GetKey(BraCode))

{

brakeValue += 255 * Time.deltaTime;

brakeValue = Mathf.Clamp(brakeValue, 0, 255);

isBra = true;

}

else

{

brakeValue = 0;

isBra = false;

}

}

void UpdateSteerValue() //更新方向盘状态

{

if (Input.GetKey(leftSteerKeyCode))

{

steerValue -= 255 * Time.deltaTime; //0.5秒左侧打死

steerValue = Mathf.Clamp(steerValue, 0, 255);

}else if(Input.GetKey(rightSteerKeyCode))

{

steerValue += 255 * Time.deltaTime; //0.5秒右侧打死

steerValue = Mathf.Clamp(steerValue, 0, 255);

}

else

{

steerValue = 128;

}

}

void UpdateGeerState() //更新挡位状态

{

if (Input.GetKeyDown(parkingKeyCode)) //设置为停车档

{

Car_Mng.Instance.gearState = GearState.ParkingGear;

}

if (Input.GetKeyDown(reversKeyCode)) //倒车档

{

Car_Mng.Instance.gearState = GearState.ReversGear;

}

if (Input.GetKeyDown(neutralKeyCode)) //空挡

{

Car_Mng.Instance.gearState = GearState.NeutralGear;

}

if (Input.GetKeyDown(forwardKeyCode)) //前进挡

{

Car_Mng.Instance.gearState = GearState.ForwardGear;

}

}

}

UI_Mng

using System.Collections;

using System.Collections.Generic;

using System.Drawing;

using UnityEngine;

using UnityEngine.UI;

public class UI_Mng : MonoBehaviour

{

static public UI_Mng Instance;

public Image ParkingBg; //停车档

public Image ForwardBg; //前进挡

public Image NeutralBg; //空挡

public Image ReversBg; //倒车档

public Image HandBrakeBg; //手刹

public Text speedText; //速度显示

public Text speedGearText; //挡位显示

public Image SwitchBg; //开关背景

public Text Switchtext; //开关显示文字

public Image AccBg; //油门

public Image BraBg; //刹车

private GearState currentGearState;

private bool currentBrakeState;

private void Awake()

{

Instance = this;

}

private void Update()

{

UpdateGearUI();

UpdateHandBrakeUI();

UpdateAccBra();

UpdateSpeed();

}

void UpdateSpeed()

{

speedText.text = Car_Mng.MeterPerSeconds2KmPerHour(Car_Mng.Instance.currentSpeed).ToString("F2")

+ " Km/h";

SpeedGear speedGear = Car_Mng.Instance.speedGear;

switch (speedGear)

{

case SpeedGear.none:

speedGearText.text = "自动挡";

break;

case SpeedGear.Speed01:

speedGearText.text = "1挡";

break;

case SpeedGear.Speed02:

speedGearText.text = "2挡";

break;

case SpeedGear.Speed03:

speedGearText.text = "3挡";

break;

case SpeedGear.Speed04:

speedGearText.text = "4挡";

break;

case SpeedGear.Speed05:

speedGearText.text = "5挡";

break;

case SpeedGear.Speed06:

speedGearText.text = "6挡";

break;

default:

break;

}

}

void UpdateAccBra()

{

if (Input_Mng.Instance.isAcc)

{

AccBg.color = UnityEngine.Color.green;

}

else

{

AccBg.color = UnityEngine.Color.white;

}

if (Input_Mng.Instance.isBra)

{

BraBg.color = UnityEngine.Color.green;

}

else

{

BraBg.color = UnityEngine.Color.white;

}

}

void UpdateHandBrakeUI()

{

if (currentBrakeState != Car_Mng.Instance.isHandBrakeON)

{

currentBrakeState = Car_Mng.Instance.isHandBrakeON;

if (currentBrakeState)

{

HandBrakeBg.color = UnityEngine.Color.red;

}

else

{

HandBrakeBg.color = UnityEngine.Color.white;

}

}

}

private void Start()

{

Car_Mng.Instance.StopCar(); //关闭车辆

OnCarShutDown();//更新UI

}

void UpdateGearUI()

{

if (currentGearState != Car_Mng.Instance.gearState)

{

currentGearState = Car_Mng.Instance.gearState;

ClearGearUI();

SetGearUI(currentGearState);

}

}

void ClearGearUI()

{

ParkingBg.color = UnityEngine.Color.white;

ForwardBg.color = UnityEngine.Color.white;

NeutralBg.color = UnityEngine.Color.white;

ReversBg.color = UnityEngine.Color.white;

}

void SetGearUI(GearState state)

{

switch (state)

{

case GearState.ForwardGear:

ForwardBg.color = UnityEngine.Color.red;

break;

case GearState.ReversGear:

ReversBg.color = UnityEngine.Color.red;

break;

case GearState.NeutralGear:

NeutralBg.color = UnityEngine.Color.red;

break;

case GearState.ParkingGear:

ParkingBg.color = UnityEngine.Color.red;

break;

}

}

public void ChangeCarState()

{

if (Car_Mng.Instance.carState == CarState.On) //如果处于开机状态,则停机

{

Car_Mng.Instance.StopCar(); //关闭车辆

OnCarShutDown();//更新UI

}else

{

Car_Mng.Instance.StartCar(); //启动车子

OnCarStart();//更新UI

}

}

private void OnCarStart() //车辆启动时更新ui

{

SwitchBg.color = UnityEngine.Color.red;

Switchtext.text = "关闭车辆";

}

private void OnCarShutDown() //车辆关闭时执行的逻辑

{

SwitchBg.color = UnityEngine.Color.green;

Switchtext.text = "启动车辆";

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。