using Code.DI; using Code.Input; using UnityEngine; namespace Code.Gameplay { public class CarController : MonoBehaviour { [SerializeField] private float motorForce = 150000f; [SerializeField] private float brakeForce = 300000f; [SerializeField] private float maxSteerAngle = 25f; [SerializeField] private float turnSpeed = 50f; [SerializeField] private Transform frontLeftWheel; [SerializeField] private Transform frontRightWheel; [SerializeField] private Transform driverCameraPoint; [SerializeField] private Camera mainCamera; [SerializeField] private float thirdPersonDistance = 6f; [SerializeField] private float thirdPersonHeight = 2.5f; [SerializeField] private float cameraFollowSpeed = 4f; private Rigidbody _rb; private bool _isFirstPerson; private IInputService _inputService; private void Awake() { _rb = GetComponent(); _rb.useGravity = true; _rb.interpolation = RigidbodyInterpolation.Interpolate; } private void Start() { var container = FindFirstObjectByType(); _inputService = container.Resolve(); SwitchToThirdPerson(); } private void Update() { if (_inputService.SwitchCameraPressed) { _isFirstPerson = !_isFirstPerson; if (_isFirstPerson) SwitchToFirstPerson(); else SwitchToThirdPerson(); } } private void FixedUpdate() { var input = _inputService.MoveInput; var force = transform.forward * input.y * motorForce; _rb.AddForce(force, ForceMode.Force); if (Mathf.Abs(input.y) < 0.1f && _rb.linearVelocity.magnitude > 0.3f) { _rb.AddForce(-_rb.linearVelocity * brakeForce * Time.fixedDeltaTime, ForceMode.Force); } var steer = input.x * maxSteerAngle; if (frontLeftWheel != null) frontLeftWheel.localRotation = Quaternion.Euler(0, steer, 0); if (frontRightWheel != null) frontRightWheel.localRotation = Quaternion.Euler(0, steer, 0); if (!(_rb.linearVelocity.magnitude > 0.5f)) return; var turn = input.x * turnSpeed * Time.fixedDeltaTime; _rb.MoveRotation(_rb.rotation * Quaternion.Euler(0, turn, 0)); } private void LateUpdate() { if (mainCamera == null) return; if (_isFirstPerson) { if (driverCameraPoint == null) return; mainCamera.transform.position = driverCameraPoint.position; mainCamera.transform.rotation = driverCameraPoint.rotation; } else { var targetPos = transform.position - transform.forward * thirdPersonDistance + Vector3.up * thirdPersonHeight; mainCamera.transform.position = Vector3.Lerp(mainCamera.transform.position, targetPos, cameraFollowSpeed * Time.deltaTime); mainCamera.transform.LookAt(transform.position + Vector3.up * 1f); } } private void SwitchToFirstPerson() { if (mainCamera != null) mainCamera.fieldOfView = 75; } private void SwitchToThirdPerson() { if (mainCamera != null) mainCamera.fieldOfView = 60; } } }