Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using UnityEngine;
- using UnityEngine.InputSystem;
- public class Car : MonoBehaviour
- {
- [Header("Wheel Details")]
- [SerializeField] private Wheel[] wheels;
- [SerializeField] private float maxTorque = 450f; // max engine torque
- [SerializeField] private float wheelFrictionCoefficient = 0.022f; // coefficient of friction for the tires, affects how much grip they have
- [SerializeField] private float brakingForce = 8000f; // max braking force the car can apply, should be much higher than max torque
- [SerializeField] private float frontAxleZ = 1.5f; // distance of front axle from the center of mass
- [SerializeField] private float rearAxleZ = -1.5f; // distance of rear axle from the center of mass
- [Header("Suspension")]
- [SerializeField] private float suspensionForce = 90f; // Spring constant
- [SerializeField] private float suspensionDamping = 2.5f; // Damping constant
- [SerializeField] private float maxSuspensionForce = 200f; // Max force the suspension can apply
- [Header("Car Details")]
- [SerializeField] private float mass = 2100f; // weight in kg
- [SerializeField] private float dragCoefficient = 0.3f; // affects how much air resistance the car has, should be between 0.25 and 0.35 for a typical car
- [SerializeField] private Vector3 centerOfGravity = Vector3.zero;
- private float rollingResistanceCoefficient; // roughly 30 times the drag coefficient
- private Engine engine;
- private InputAction throttleInput;
- private InputAction steeringInput;
- private InputAction brakeInput;
- private Rigidbody rb;
- private float throttle;
- private float steering;
- private float brake;
- private float weight;
- private float wheelBase;
- private float driveWheelRPM = 0f;
- private float torque = 0f;
- private Vector3 dragForce = Vector3.zero;
- private Vector3 rollingResistanceForce = Vector3.zero;
- private float velocity = 0f;
- void Start()
- {
- engine = GetComponent<Engine>();
- rb = GetComponent<Rigidbody>();
- throttleInput = InputSystem.actions.FindAction("Throttle");
- steeringInput = InputSystem.actions.FindAction("Steer");
- brakeInput = InputSystem.actions.FindAction("Brake");
- rollingResistanceCoefficient = 30 * dragCoefficient;
- weight = mass * Physics.gravity.magnitude;
- wheelBase = Mathf.Abs(frontAxleZ - rearAxleZ);
- engine.StartEngine();
- }
- void Update()
- {
- throttle = throttleInput.ReadValue<float>();
- steering = steeringInput.ReadValue<float>();
- brake = brakeInput.ReadValue<float>();
- }
- void FixedUpdate()
- {
- velocity = rb.linearVelocity.magnitude;
- torque = engine.GetTorque(wheels[0].radius, throttle);
- // Negative forces
- dragForce = -velocity * dragCoefficient * rb.linearVelocity.normalized;
- rollingResistanceForce = -velocity * rollingResistanceCoefficient * rb.linearVelocity.normalized; // eventually make per wheel based on weight distribution
- // RPM calculations
- driveWheelRPM = (velocity / (2 * Mathf.PI * wheels[0].radius)) * 60f;
- engine.SetRPM(driveWheelRPM * engine.gearRatios[engine.gear] * engine.finalDriveRatio);
- // Weight distribution for front and rear axles
- float acceleration = velocity / Time.deltaTime;
- float yForce = acceleration * mass * (centerOfGravity.y / wheelBase);
- float frontWeight = (weight * (Mathf.Abs(frontAxleZ - centerOfGravity.z) / wheelBase)) - yForce;
- float rearWeight = (weight * (Mathf.Abs(rearAxleZ - centerOfGravity.z) / wheelBase)) + yForce;
- // Debug.Log($"rpm: {engine.rpm}, drive wheel rpm: {driveWheelRPM}, torque: {torque} ft-lb");
- // Debug.Log($"speed: {rb.linearVelocity.magnitude * 3.6f} km/h");
- // Debug.Log($"rear weight: {rearWeight} N, front weight: {frontWeight} N, y force: {yForce} N");
- // Debug.Log($"acceleration: {acceleration} m/s^2");
- foreach (Wheel wheel in wheels)
- {
- GameObject wheelObject = wheel.gameObject;
- Transform wheelTransform = wheelObject.transform;
- if (wheel.powered)
- {
- Vector3 driveForce = (transform.forward * torque + dragForce + rollingResistanceForce);
- Vector3 brakeForce = (brake * brakingForce * -transform.forward + dragForce + rollingResistanceForce);
- wheelTransform.Rotate(Vector3.right, driveWheelRPM * 360f * Time.fixedDeltaTime); // rotate the wheel based on its RPM
- Debug.Log($"drive force: {driveForce.magnitude} N, brake force: {brakeForce.magnitude} N ");
- if (rb.linearVelocity.normalized.z > 1f)
- {
- rb.AddForceAtPosition(brakeForce, wheelTransform.position);
- }
- rb.AddForceAtPosition(driveForce, wheelTransform.position);
- }
- if (wheel.steering)
- {
- float targetAngle = wheel.steerAngle * steering;
- Quaternion targetRotation = Quaternion.Euler(0f, targetAngle, 0f);
- wheelTransform.localRotation = Quaternion.Lerp(
- wheelTransform.localRotation,
- targetRotation,
- Time.fixedDeltaTime * 100f
- );
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment