using RaceFields.Vehicles; using UnityEngine; namespace RaceFields.CameraSystem { [RequireComponent(typeof(Camera))] public sealed class RearViewMirrorCamera : MonoBehaviour { [SerializeField] private Transform target; [SerializeField] private bool autoFindTarget = true; [SerializeField] private float targetSearchInterval = 0.35f; [SerializeField] private Vector3 localOffset = new Vector3(0f, 2.1f, 0.6f); [SerializeField] private float lookUpBias = 0.08f; [SerializeField] private float positionLerp = 18f; [SerializeField] private float rotationLerp = 18f; private Camera mirrorCamera; private float nextTargetSearchTime; private void Awake() { mirrorCamera = GetComponent(); mirrorCamera.enabled = true; } private void LateUpdate() { ResolveTarget(); if (target == null) return; Vector3 desiredPosition = target.TransformPoint(localOffset); Vector3 lookDirection = -target.forward + Vector3.up * lookUpBias; Quaternion desiredRotation = Quaternion.LookRotation(lookDirection.normalized, Vector3.up); float positionStep = 1f - Mathf.Exp(-positionLerp * Time.deltaTime); float rotationStep = 1f - Mathf.Exp(-rotationLerp * Time.deltaTime); transform.position = Vector3.Lerp(transform.position, desiredPosition, positionStep); transform.rotation = Quaternion.Slerp(transform.rotation, desiredRotation, rotationStep); } public void SetTarget(Transform newTarget, bool snap) { target = newTarget; if (snap && target != null) SnapToTarget(); } private void SnapToTarget() { transform.position = target.TransformPoint(localOffset); Vector3 lookDirection = -target.forward + Vector3.up * lookUpBias; transform.rotation = Quaternion.LookRotation(lookDirection.normalized, Vector3.up); } private void ResolveTarget() { if (target != null || !autoFindTarget) return; if (Time.unscaledTime < nextTargetSearchTime) return; nextTargetSearchTime = Time.unscaledTime + targetSearchInterval; ArcadeBuggyController controller = Object.FindFirstObjectByType(); if (controller != null) SetTarget(controller.transform, true); } } }