Files
AppleHillsProduction/Assets/Scripts/AppleHillsCamera/CameraScreenAdapter.cs
2025-10-13 16:31:52 +02:00

128 lines
4.6 KiB
C#

using UnityEngine;
using Unity.Cinemachine;
using System;
namespace AppleHillsCamera
{
/// <summary>
/// Adjusts the camera's orthographic size to match the target width from a ScreenReferenceMarker.
/// Works with both regular cameras and Cinemachine virtual cameras.
/// </summary>
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;
// 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<Camera>();
// Try to get Cinemachine camera if no regular camera or if both exist
_virtualCamera = GetComponent<CinemachineCamera>();
// 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;
}
}
/// <summary>
/// Manually trigger camera adjustment to match the reference width.
/// </summary>
public void AdjustCamera()
{
if (referenceMarker == null)
{
Debug.LogWarning("CameraScreenAdapter: Missing reference marker.");
return;
}
// 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)
float orthoSize = (targetWidth / 2f) * screenAspect;
// Apply the calculated size to the camera
if (_usingCinemachine)
{
// Apply to Cinemachine virtual camera
var lens = _virtualCamera.Lens;
lens.OrthographicSize = orthoSize;
_virtualCamera.Lens = lens;
Debug.Log($"Cinemachine Camera adapted: Width={targetWidth}, Aspect={screenAspect:F2}, OrthoSize={orthoSize:F2}");
}
else
{
// Apply to regular camera
if (_regularCamera.orthographic)
{
_regularCamera.orthographicSize = orthoSize;
Debug.Log($"Camera adapted: Width={targetWidth}, Aspect={screenAspect:F2}, OrthoSize={orthoSize:F2}");
}
else
{
Debug.LogWarning("CameraScreenAdapter: Regular camera is not in orthographic mode.");
return;
}
}
// Notify subscribers that the camera has been adjusted
OnCameraAdjusted?.Invoke();
}
/// <summary>
/// Gets the camera component being controlled by this adapter
/// </summary>
public Camera GetControlledCamera()
{
return _usingCinemachine ? _virtualCamera.GetComponent<Camera>() : _regularCamera;
}
}
}