130 lines
3.7 KiB
C#
130 lines
3.7 KiB
C#
using UnityEngine;
|
|
using UnityEngine.Rendering.Universal;
|
|
using AibisDream.Kit;
|
|
using AibisDream.Utility;
|
|
|
|
namespace AibisDream.Framework
|
|
{
|
|
[RequireComponent(typeof(Camera))]
|
|
public class CameraAspectAdapter : MonoBehaviour
|
|
{
|
|
private Camera _targetCamera;
|
|
|
|
private Vector2Int _lastScreenSize;
|
|
private Rect _targetRect;
|
|
private IUnRegister _resolutionChangeUnRegister;
|
|
|
|
private void Awake()
|
|
{
|
|
_targetCamera = GetComponent<Camera>();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
_lastScreenSize = new Vector2Int(Screen.width, Screen.height);
|
|
CalculateTargetRect();
|
|
ApplyToAllCameras();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
_resolutionChangeUnRegister = EnumEventSystem.Global.Register(
|
|
SettingChangeEvent.DisplayChanged, OnResolutionChanged);
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
_resolutionChangeUnRegister?.UnRegister();
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
bool screenChanged = Screen.width != _lastScreenSize.x
|
|
|| Screen.height != _lastScreenSize.y;
|
|
if (screenChanged)
|
|
{
|
|
_lastScreenSize = new Vector2Int(Screen.width, Screen.height);
|
|
CalculateTargetRect();
|
|
}
|
|
|
|
ApplyToAllCameras();
|
|
}
|
|
|
|
public void Refresh(bool reset = false)
|
|
{
|
|
if (_targetCamera == null) return;
|
|
|
|
if (reset)
|
|
{
|
|
_targetRect = new Rect(0, 0, 1, 1);
|
|
}
|
|
else
|
|
{
|
|
CalculateTargetRect();
|
|
}
|
|
|
|
ApplyToAllCameras();
|
|
}
|
|
|
|
private void OnResolutionChanged()
|
|
{
|
|
_lastScreenSize = new Vector2Int(Screen.width, Screen.height);
|
|
CalculateTargetRect();
|
|
ApplyToAllCameras();
|
|
}
|
|
|
|
private void CalculateTargetRect()
|
|
{
|
|
const float Epsilon = 0.0001f;
|
|
float windowAspect = (float)Screen.width / Screen.height;
|
|
float targetAspect = ConstRef.TargetAspect;
|
|
float diff = windowAspect - targetAspect;
|
|
|
|
if (Mathf.Abs(diff) < Epsilon)
|
|
{
|
|
_targetRect = new Rect(0, 0, 1, 1);
|
|
}
|
|
else if (diff < 0)
|
|
{
|
|
float scaleHeight = windowAspect / targetAspect;
|
|
_targetRect = new Rect(0, (1f - scaleHeight) / 2f, 1f, scaleHeight);
|
|
}
|
|
else
|
|
{
|
|
float scaleWidth = targetAspect / windowAspect;
|
|
_targetRect = new Rect((1f - scaleWidth) / 2f, 0, scaleWidth, 1f);
|
|
}
|
|
}
|
|
|
|
private void ApplyToAllCameras()
|
|
{
|
|
ApplyRect(_targetCamera);
|
|
|
|
if (_targetCamera != null &&
|
|
_targetCamera.TryGetComponent(out UniversalAdditionalCameraData cameraData))
|
|
{
|
|
foreach (var overlay in cameraData.cameraStack)
|
|
{
|
|
if (overlay != null)
|
|
ApplyRect(overlay);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ApplyRect(Camera camera)
|
|
{
|
|
if (camera == null) return;
|
|
|
|
const float Epsilon = 0.0001f;
|
|
Rect current = camera.rect;
|
|
if (Mathf.Abs(current.x - _targetRect.x) > Epsilon ||
|
|
Mathf.Abs(current.y - _targetRect.y) > Epsilon ||
|
|
Mathf.Abs(current.width - _targetRect.width) > Epsilon ||
|
|
Mathf.Abs(current.height - _targetRect.height) > Epsilon)
|
|
{
|
|
camera.rect = _targetRect;
|
|
}
|
|
}
|
|
}
|
|
}
|