using UnityEngine; public class RacingCamera : MonoBehaviour { public enum CameraMode { Follow, Orbit, Hood, Bumper } [Header("Target")] public Transform carTarget; public Rigidbody carRigidbody; [Header("Camera Mode")] public CameraMode currentMode = CameraMode.Follow; public KeyCode switchKey = KeyCode.C; [Header("Follow Mode Settings")] public Vector3 followOffset = new Vector3(0, 3, -8); public float followSmoothTime = 0.1f; [Header("Orbit Mode Settings")] public float orbitDistance = 10f; public float orbitHeight = 3f; public float orbitSpeed = 2f; private float orbitAngle = 0f; [Header("First Person Settings")] public Transform hoodCameraPosition; public Transform bumperCameraPosition; [Header("Look Settings")] public float lookAheadDistance = 5f; public Vector3 lookAtOffset = new Vector3(0, 1.5f, 0); private Vector3 velocity = Vector3.zero; private Camera cam; void Start() { cam = GetComponent(); if (carRigidbody == null && carTarget != null) carRigidbody = carTarget.GetComponent(); } void Update() { // Переключение режимов камеры if (Input.GetKeyDown(switchKey)) { SwitchCameraMode(); } } void LateUpdate() { if (carTarget == null) return; switch (currentMode) { case CameraMode.Follow: UpdateFollowCamera(); break; case CameraMode.Orbit: UpdateOrbitCamera(); break; case CameraMode.Hood: UpdateFirstPersonCamera(hoodCameraPosition); break; case CameraMode.Bumper: UpdateFirstPersonCamera(bumperCameraPosition); break; } } void SwitchCameraMode() { currentMode = (CameraMode)(((int)currentMode + 1) % 4); Debug.Log("Camera mode: " + currentMode); } void UpdateFollowCamera() { // Рассчитываем позицию с учетом скорости Vector3 targetPosition = CalculateFollowPosition(); // Плавное перемещение transform.position = Vector3.SmoothDamp( transform.position, targetPosition, ref velocity, followSmoothTime ); // Направление взгляда с опережением Vector3 lookTarget = carTarget.position + carTarget.forward * lookAheadDistance + lookAtOffset; transform.LookAt(lookTarget); } Vector3 CalculateFollowPosition() { Vector3 basePosition = carTarget.position + carTarget.TransformDirection(followOffset); // Динамическое смещение на основе скорости if (carRigidbody != null) { float speedFactor = Mathf.Clamp01(carRigidbody.linearVelocity.magnitude / 50f); Vector3 speedOffset = carTarget.forward * speedFactor * -3f; basePosition += speedOffset; } return basePosition; } void UpdateOrbitCamera() { // Автоматическое вращение вокруг машины orbitAngle += orbitSpeed * Time.deltaTime; // Рассчитываем позицию по окружности float x = Mathf.Sin(orbitAngle) * orbitDistance; float z = Mathf.Cos(orbitAngle) * orbitDistance; Vector3 orbitPosition = carTarget.position + new Vector3(x, orbitHeight, z); transform.position = orbitPosition; transform.LookAt(carTarget.position + lookAtOffset); } void UpdateFirstPersonCamera(Transform cameraPosition) { if (cameraPosition == null) { // Резервная позиция transform.position = carTarget.position + carTarget.forward * 1f + Vector3.up * 1.5f; transform.rotation = carTarget.rotation; return; } transform.position = cameraPosition.position; transform.rotation = cameraPosition.rotation; // Добавляем небольшую тряску на скорости if (carRigidbody != null) { float shakeAmount = carRigidbody.linearVelocity.magnitude * 0.001f; transform.position += Random.insideUnitSphere * shakeAmount; } } // Визуализация в редакторе void OnDrawGizmosSelected() { if (carTarget != null) { Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(carTarget.position + lookAtOffset, 0.5f); Gizmos.DrawLine(transform.position, carTarget.position + lookAtOffset); } } }