Skip to content

Instantly share code, notes, and snippets.

@zsoi
Created November 3, 2015 15:52
Show Gist options
  • Save zsoi/e5d9348158785ffab0fe to your computer and use it in GitHub Desktop.
Save zsoi/e5d9348158785ffab0fe to your computer and use it in GitHub Desktop.
Unity3D component which enforces a certain aspect ratio to the viewport of a camera, so that the camera always renders with this aspect rather than the actual screen aspect
using UnityEngine;
using System.Collections;
namespace ZS.Tools
{
/// <summary>
/// Adjusts the camera viewport so the actually drawn portion is always of a specific aspect ratio,
/// uninfluenced by the actual screen size. The viewport maximize its covered space.
/// </summary>
[RequireComponent(typeof(Camera)), ExecuteInEditMode]
public class CameraFixedAspectViewport : MonoBehaviour
{
/// <summary>
/// Different pre-set aspect ratios
/// </summary>
public enum AspectRatio
{
/// <summary>
/// Custom aspect ratio, <see cref="CustomAspect">CustomAspect</see> must be set then!
/// </summary>
Custom,
/// <summary>
/// 16:9
/// </summary>
Aspect16to9,
/// <summary>
/// 16:10
/// </summary>
Aspect16to10,
/// <summary>
/// 4:3
/// </summary>
Aspect4to3,
/// <summary>
/// 5:4
/// </summary>
Aspect5to4,
/// <summary>
/// 1:1
/// </summary>
Aspect1to1,
}
[Tooltip("Which aspect the viewport should keep")]
public AspectRatio Aspect;
[Tooltip("When Aspect is set to Custom, this ratio (W/H) is used for aspect calculation")]
public float CustomAspect = 1F;
[Tooltip("Enabled continous recalculation of the viewport on each frame")]
public bool ContinousUpdate = false;
/// <summary>
/// Reference to the camera component for faster access
/// </summary>
Camera mCamera;
void Start()
{
mCamera = GetComponent<Camera>();
}
void Update()
{
if (ContinousUpdate)
{
ApplyToViewport();
}
}
/// <summary>
/// Corrects the viewport of the camera so the viewport resembles the intended aspect ratio
/// </summary>
public void ApplyToViewport()
{
float ratio = CustomAspect;
switch (Aspect)
{
case AspectRatio.Aspect16to9:
ratio = 16F / 9F;
break;
case AspectRatio.Aspect16to10:
ratio = 16F / 10F;
break;
case AspectRatio.Aspect4to3:
ratio = 4F / 3F;
break;
case AspectRatio.Aspect5to4:
ratio = 5F / 4F;
break;
case AspectRatio.Aspect1to1:
ratio = 1F;
break;
// Custom: Fall-through
}
// Current aspect of the whole screen
float screenAspect = Screen.width / (float)Screen.height;
// How much does the screen aspect be adjusted to fit the intended aspect?
float aspectAdjustment = screenAspect / ratio;
// >1F means bars to the left and right
if (aspectAdjustment >= 1F)
{
mCamera.rect = new Rect((1F - 1F / aspectAdjustment) * 0.5F, 0F, 1F / aspectAdjustment, 1F);
}
// <1F means bars on the top and bottom
else
{
mCamera.rect = new Rect(0F, (1F - aspectAdjustment) * 0.5F, 1F, aspectAdjustment);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment