WheelDrive.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Traffic Simulation
  2. // https://github.com/mchrbn/unity-traffic-simulation
  3. // Based on the Vehicle Tools package from Unity
  4. using UnityEngine;
  5. using System;
  6. namespace TrafficSimulation{
  7. [Serializable]
  8. public enum DriveType{
  9. RearWheelDrive,
  10. FrontWheelDrive,
  11. AllWheelDrive
  12. }
  13. [Serializable]
  14. public enum UnitType{
  15. KMH,
  16. MPH
  17. }
  18. public class WheelDrive : MonoBehaviour
  19. {
  20. [Tooltip("Downforce applied to the vehicle")]
  21. public float downForce = 100f;
  22. [Tooltip("Maximum steering angle of the wheels")]
  23. public float maxAngle = 30f;
  24. [Tooltip("Speed at which we will reach the above steering angle (lerp)")]
  25. public float steeringLerp = 5f;
  26. [Tooltip("Max speed (in unit choosen below) when the vehicle is about to steer")]
  27. public float steeringSpeedMax = 20f;
  28. [Tooltip("Maximum torque applied to the driving wheels")]
  29. public float maxTorque = 300f;
  30. [Tooltip("Maximum brake torque applied to the driving wheels")]
  31. public float brakeTorque = 30000f;
  32. [Tooltip("Unit Type")]
  33. public UnitType unitType;
  34. [Tooltip("Min Speed - when driving (not including stops/brakes), in the unit choosen above. Should be > 0.")]
  35. public float minSpeed = 5;
  36. [Tooltip("Max Speed in the unit choosen above")]
  37. public float maxSpeed = 50;
  38. [Tooltip("Drag the wheel shape here.")]
  39. public GameObject leftWheelShape;
  40. public GameObject rightWheelShape;
  41. [Tooltip("Whether you want to animate the wheels")]
  42. public bool animateWheels = true;
  43. [Tooltip("The vehicle's drive type: rear-wheels drive, front-wheels drive or all-wheels drive.")]
  44. public DriveType driveType;
  45. private WheelCollider[] wheels;
  46. private float currentSteering = 0f;
  47. private void Start()
  48. {
  49. wheels = GetComponentsInChildren<WheelCollider>();
  50. for (int i = 0; i < wheels.Length; ++i)
  51. {
  52. var wheel = wheels[i];
  53. // Create wheel shapes only when needed.
  54. if (leftWheelShape != null && wheel.transform.localPosition.x < 0)
  55. {
  56. var ws = Instantiate(leftWheelShape);
  57. ws.transform.parent = wheel.transform;
  58. //ws.transform.localPosition = Vector3.zero;
  59. }
  60. else if (rightWheelShape != null && wheel.transform.localPosition.x > 0)
  61. {
  62. var ws = Instantiate(rightWheelShape);
  63. ws.transform.parent = wheel.transform;
  64. //ws.transform.localPosition = Vector3.zero;
  65. }
  66. wheel.ConfigureVehicleSubsteps(10, 1, 1);
  67. }
  68. }
  69. private void OnDisable()
  70. {
  71. ResetWheels();
  72. }
  73. private void ResetWheels()
  74. {
  75. //Debug.Log("Reset Steering!");
  76. this.currentSteering = 0f;
  77. }
  78. public void Move(float _acceleration, float _steering, float _brake)
  79. {
  80. float nSteering = Mathf.Lerp(currentSteering, _steering, Time.deltaTime * steeringLerp);
  81. currentSteering = nSteering;
  82. Rigidbody rb = this.GetComponent<Rigidbody>();
  83. float angle = maxAngle * nSteering;
  84. float torque = maxTorque * _acceleration;
  85. float handBrake = _brake > 0 ? brakeTorque : 0;
  86. foreach (WheelCollider wheel in wheels){
  87. // Steer front wheels only
  88. if (wheel.transform.localPosition.z > 0) wheel.steerAngle = angle;
  89. if (wheel.transform.localPosition.z < 0) wheel.brakeTorque = handBrake;
  90. if (wheel.transform.localPosition.z < 0 && driveType != DriveType.FrontWheelDrive) wheel.motorTorque = torque;
  91. if (wheel.transform.localPosition.z >= 0 && driveType != DriveType.RearWheelDrive) wheel.motorTorque = torque;
  92. // Update visual wheels if allowed
  93. if(animateWheels){
  94. Quaternion q;
  95. Vector3 p;
  96. wheel.GetWorldPose(out p, out q);
  97. Transform shapeTransform = wheel.transform.GetChild (0);
  98. shapeTransform.position = p;
  99. shapeTransform.rotation = q;
  100. }
  101. }
  102. //Apply speed
  103. float s = GetSpeedUnit(rb.velocity.magnitude);
  104. if(s > maxSpeed) rb.velocity = GetSpeedMS(maxSpeed) * rb.velocity.normalized;
  105. //Apply downforce
  106. rb.AddForce(-transform.up * downForce * rb.velocity.magnitude);
  107. }
  108. public float GetSpeedMS(float _s){
  109. return unitType == UnitType.KMH ? _s / 3.6f : _s / 2.237f;
  110. }
  111. public float GetSpeedUnit(float _s){
  112. return unitType == UnitType.KMH ? _s * 3.6f : _s * 2.237f;
  113. }
  114. }
  115. }