using UnityEngine; using Unity.Cinemachine; using System; using Core; namespace AppleHillsCamera { /// /// Adjusts the camera's orthographic size to match the target width from a ScreenReferenceMarker. /// Works with both regular cameras and Cinemachine virtual cameras. /// public class CameraScreenAdapter : MonoBehaviour { [Tooltip("Reference that defines the target width to match")] public ScreenReferenceMarker referenceMarker; [Tooltip("Whether to adjust the camera automatically on Start")] public bool adjustOnStart = true; [Tooltip("Whether to adjust the camera automatically when the screen size changes")] public bool adjustOnScreenResize = true; [Tooltip("Enable debug logging")] public bool debugLogging; // Event that other components can subscribe to when camera is adjusted public event Action OnCameraAdjusted; private Camera _regularCamera; private CinemachineCamera _virtualCamera; private int _lastScreenWidth; private int _lastScreenHeight; private bool _usingCinemachine; private void Awake() { // Try to get regular camera first _regularCamera = GetComponent(); // Try to get Cinemachine camera if no regular camera or if both exist _virtualCamera = GetComponent(); // Determine which camera type we're using _usingCinemachine = _virtualCamera != null; _lastScreenWidth = Screen.width; _lastScreenHeight = Screen.height; if (!_usingCinemachine && _regularCamera == null) { Debug.LogError("CameraScreenAdapter: No camera component found. Add this script to a GameObject with either Camera or CinemachineCamera component."); enabled = false; return; } } private void Start() { if (adjustOnStart) { AdjustCamera(); } } private void Update() { if (adjustOnScreenResize && (Screen.width != _lastScreenWidth || Screen.height != _lastScreenHeight)) { AdjustCamera(); _lastScreenWidth = Screen.width; _lastScreenHeight = Screen.height; } } /// /// Manually trigger camera adjustment to match the reference width or height. /// public void AdjustCamera() { if (referenceMarker == null) { Logging.Warning("CameraScreenAdapter: Missing reference marker."); return; } float orthoSize; if (referenceMarker.scalingMode == ScreenReferenceMarker.ScalingMode.Width) { // Calculate the orthographic size based on the target width and screen aspect ratio float targetWidth = referenceMarker.targetWidth; float screenAspect = (float)Screen.height / Screen.width; // Orthographic size is half the height, so we calculate: // orthoSize = (targetWidth / 2) * (screenHeight / screenWidth) orthoSize = (targetWidth / 2f) * screenAspect; if (debugLogging) { Logging.Debug($"CameraScreenAdapter: Scaling by Width - targetWidth={targetWidth:F2}, aspect={screenAspect:F2}, orthoSize={orthoSize:F2}"); } } else // ScalingMode.Height { // When scaling by height, the orthographic size directly matches half the target height float targetHeight = referenceMarker.targetHeight; orthoSize = targetHeight / 2f; if (debugLogging) { Logging.Debug($"CameraScreenAdapter: Scaling by Height - targetHeight={targetHeight:F2}, orthoSize={orthoSize:F2}"); } } // Apply the calculated size to the camera if (_usingCinemachine) { // Apply to Cinemachine virtual camera var lens = _virtualCamera.Lens; lens.OrthographicSize = orthoSize; _virtualCamera.Lens = lens; if (debugLogging) { Logging.Debug($"Cinemachine Camera adapted: OrthoSize={orthoSize:F2}"); } } else { // Apply to regular camera if (_regularCamera.orthographic) { _regularCamera.orthographicSize = orthoSize; if (debugLogging) { Logging.Debug($"Camera adapted: OrthoSize={orthoSize:F2}"); } } else { Logging.Warning("CameraScreenAdapter: Regular camera is not in orthographic mode."); return; } } // Notify subscribers that the camera has been adjusted OnCameraAdjusted?.Invoke(); } /// /// Gets the camera component being controlled by this adapter /// public Camera GetControlledCamera() { return _usingCinemachine ? _virtualCamera.GetComponent() : _regularCamera; } } }