Files
2026-01-27 17:42:28 +03:00

115 lines
3.7 KiB
C#

using Code.DI;
using Code.Input;
using UnityEngine;
namespace Code.Gameplay
{
[RequireComponent(typeof(Rigidbody))]
public class CarController : MonoBehaviour
{
[Header("Physics")]
[SerializeField] private float motorForce = 150000;
[SerializeField] private float brakeForce = 300000;
[SerializeField] private float maxSteerAngle = 25f;
[SerializeField] private float turnSpeed = 50;
[Header("Wheels")]
[SerializeField] private Transform frontLeftWheel;
[SerializeField] private Transform frontRightWheel;
[Header("Camera")]
[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 float _lastSwitchTime;
private const float SwitchCooldown = 0.5f;
private void Awake()
{
_rb = GetComponent<Rigidbody>();
}
private void Start()
{
var container = FindFirstObjectByType<DIContainer>();
_inputService = container.Resolve<IInputService>();
SwitchToThirdPerson();
}
private void Update()
{
if (_inputService.SwitchCameraPressed)
{
if (Time.time - _lastSwitchTime >= SwitchCooldown)
{
_isFirstPerson = !_isFirstPerson;
if (_isFirstPerson) SwitchToFirstPerson();
else SwitchToThirdPerson();
_lastSwitchTime = Time.time;
}
}
}
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 steerInput = input.x;
if (input.y < 0)
steerInput = -input.x;
var steer = steerInput * maxSteerAngle;
if (frontLeftWheel) frontLeftWheel.localRotation = Quaternion.Euler(0, steer, 0);
if (frontRightWheel) frontRightWheel.localRotation = Quaternion.Euler(0, steer, 0);
if (!(_rb.linearVelocity.magnitude > 0.5f)) return;
var turn = steerInput * turnSpeed * Time.fixedDeltaTime;
_rb.MoveRotation(_rb.rotation * Quaternion.Euler(0, turn, 0));
}
private void LateUpdate()
{
if (!mainCamera) return;
if (_isFirstPerson)
{
if (driverCameraPoint)
{
mainCamera.transform.localPosition = driverCameraPoint.localPosition;
mainCamera.transform.localRotation = driverCameraPoint.localRotation;
}
}
else
{
mainCamera.transform.localPosition = new Vector3(0, 5, -8);
mainCamera.transform.localRotation = Quaternion.Euler(20, 0, 0);
}
}
private void SwitchToFirstPerson()
{
if (mainCamera) mainCamera.fieldOfView = 75;
}
private void SwitchToThirdPerson()
{
if (mainCamera) mainCamera.fieldOfView = 60;
}
}
}