Skip to content

Instantly share code, notes, and snippets.

@docky
Created May 3, 2023 19:12
Show Gist options
  • Select an option

  • Save docky/c11251afc85321e8746e8f820a11cdc6 to your computer and use it in GitHub Desktop.

Select an option

Save docky/c11251afc85321e8746e8f820a11cdc6 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
public class CameraAspectRatioMinMax : MonoBehaviour
{
[BoxGroup("Render Camera")]
[Required] [SerializeField] private Camera cam;
[BoxGroup("Border colour")]
[Required] [SerializeField] private Camera dummyCamera;
[SerializeField] private Color barColor = Color.black;
[BoxGroup("Ratio Limits")]
[SerializeField, MinValue(0.5f), MaxValue(5f)] private float minRatio = 1.5f;
[SerializeField, MinValue("minRatio"), MaxValue(5f)] private float maxRatio = 2.4f;
[BoxGroup("Repeat Timer")]
[SerializeField] private bool repeatAutomatically = false;
[SuffixLabel("seconds")][SerializeField] private float repeatTimer = 0.5f;
[ReadOnly][SerializeField] private bool isRunning = true;
[BoxGroup("Current Sizes")]
[ReadOnly][SerializeField] private Vector2Int viewportSize;
[ReadOnly][SerializeField] private float viewportAspectRatio = 1.777f;
[ReadOnly][SerializeField] private Rect cameraRect;
private void Update()
{
if (isRunning) return;
if (!repeatAutomatically) return;
StopAllCoroutines();
StartCoroutine(RepeatTimer());
}
[Button]
void SetupDummyCamera()
{
if (dummyCamera == null)
{
GameObject aspectBarColor = new GameObject("Aspect Bar Color");
dummyCamera = aspectBarColor.AddComponent<Camera>();
aspectBarColor.transform.parent = transform;
}
dummyCamera.clearFlags = CameraClearFlags.SolidColor;
dummyCamera.backgroundColor = barColor;
dummyCamera.cullingMask = (LayerMask)0;
dummyCamera.depth = -99;
}
[Button]
void UpdateCameraViewport()
{
cam.rect = new Rect(0, 0, 1, 1);
var size = Screen.currentResolution;
viewportSize = new Vector2Int(cam.pixelWidth, cam.pixelHeight);
viewportAspectRatio = GetAspect(viewportSize.x, viewportSize.y);
// resolution has changed
RefreshAspectRatio();
}
public bool CheckHasChanged()
{
return (viewportSize.y != cam.pixelHeight || viewportSize.x != cam.pixelWidth);
}
[Button]
void ResetCamera()
{
cam.rect = new Rect(0, 0, 1, 1);
}
public void RefreshAspectRatio()
{
// aspect ratio is within limits
if (viewportAspectRatio < maxRatio && viewportAspectRatio > minRatio)
return;
// letterbox (horizontal bars)
if (viewportAspectRatio < minRatio)
{
CameraSetWidthHeight(1f, viewportAspectRatio / minRatio);
return;
}
// pillarbox (side bars)
CameraSetWidthHeight(maxRatio / viewportAspectRatio, 1f);
}
void CameraSetWidthHeight(float width, float height)
{
cameraRect.Set((1f - width) * 0.5f, (1f - height) * 0.5f, width, height);
cam.rect = cameraRect;
}
float GetAspect(float width, float height)
{
return width / height;
}
IEnumerator RepeatTimer()
{
isRunning = true;
while (repeatAutomatically)
{
if (CheckHasChanged()) UpdateCameraViewport();
yield return new WaitForSeconds(repeatTimer);
}
isRunning = false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment