using UnityEngine; using UnityEngine.InputSystem; [RequireComponent(typeof(Rigidbody2D))] public class CarLogic : MonoBehaviour { public InputAction steeringAction; public InputAction accelerationAction; public InputAction brakeAction; public float accelerationAmount = 10; [Tooltip("In degrees")] public float steeringAnglePerSecond = 10; public float maxAcceleration = 100; public float brakingAmount; public float wheelAccelerationFactor = 6.0f; private Rigidbody2D _rigidbody; private Transform _transform; private float _currentAcceleration; private int _wheelOnRoadCount = 0; private float _maxAcceleration; private float _wheelAccelerationOffset; public float CurrentAccelerationRatio() { return _currentAcceleration / maxAcceleration; } private void Awake() { _rigidbody = GetComponent(); _transform = transform; _maxAcceleration = maxAcceleration; _wheelAccelerationOffset = wheelAccelerationFactor - 4; } private void OnEnable() { steeringAction.Enable(); accelerationAction.Enable(); brakeAction.Enable(); var wheels = GetComponentsInChildren(); foreach (var wheel in wheels) { wheel.wheelOffRoad = WheelOffRoad; wheel.wheelOnRoad = WheelOnRoad; } _wheelOnRoadCount = 0; } private void OnDisable() { steeringAction.Disable(); accelerationAction.Disable(); brakeAction.Disable(); } private void WheelOffRoad() { _wheelOnRoadCount--; _maxAcceleration = ((_wheelOnRoadCount + _wheelAccelerationOffset) / wheelAccelerationFactor) * maxAcceleration; } private void WheelOnRoad() { _wheelOnRoadCount++; _maxAcceleration = ((_wheelOnRoadCount + _wheelAccelerationOffset) / wheelAccelerationFactor) * maxAcceleration; } private void Update() { var steeringValue = steeringAction.ReadValue(); var accelerationValue = accelerationAction.ReadValue(); var brakeValue = brakeAction.ReadValue(); if (accelerationValue <= 0) { _currentAcceleration -= _rigidbody.drag * Time.deltaTime; } _currentAcceleration += accelerationValue * accelerationAmount * Time.deltaTime; _currentAcceleration -= brakeValue * brakingAmount * Time.deltaTime; // TODO: reverse logic. _currentAcceleration = Mathf.Clamp(_currentAcceleration, 0, _maxAcceleration); if (_currentAcceleration > 0.01) { var newAngle = steeringValue * steeringAnglePerSecond * Time.deltaTime; _transform.Rotate(Vector3.forward, newAngle, Space.World); } _rigidbody.velocity = _transform.up * _currentAcceleration; } }