Skip to content

Instantly share code, notes, and snippets.

@yasirkula
Last active October 24, 2024 04:13
Show Gist options
  • Save yasirkula/a0df635b24b2e4503090c148567392fd to your computer and use it in GitHub Desktop.
Save yasirkula/a0df635b24b2e4503090c148567392fd to your computer and use it in GitHub Desktop.
A script to fix the horizontal FOV/orthographic size of a camera to a specified value in Unity
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent( typeof( Camera ) )]
public class HorizontalCamera : MonoBehaviour
{
private Camera m_camera;
private float lastAspect;
#pragma warning disable 0649
[SerializeField]
private float m_fieldOfView = 60f;
public float FieldOfView
{
get { return m_fieldOfView; }
set
{
if( m_fieldOfView != value )
{
m_fieldOfView = value;
RefreshCamera();
}
}
}
[SerializeField]
private float m_orthographicSize = 5f;
public float OrthographicSize
{
get { return m_orthographicSize; }
set
{
if( m_orthographicSize != value )
{
m_orthographicSize = value;
RefreshCamera();
}
}
}
#pragma warning restore 0649
private void OnEnable()
{
RefreshCamera();
#if UNITY_EDITOR
UnityEditor.EditorApplication.update -= Update;
UnityEditor.EditorApplication.update += Update;
#endif
}
private void Update()
{
float aspect = m_camera.aspect;
if( aspect != lastAspect )
AdjustCamera( aspect );
}
public void RefreshCamera()
{
if( !m_camera )
m_camera = GetComponent<Camera>();
AdjustCamera( m_camera.aspect );
}
private void AdjustCamera( float aspect )
{
lastAspect = aspect;
// Credit: https://forum.unity.com/threads/how-to-calculate-horizontal-field-of-view.16114/#post-2961964
float _1OverAspect = 1f / aspect;
m_camera.fieldOfView = 2f * Mathf.Atan( Mathf.Tan( m_fieldOfView * Mathf.Deg2Rad * 0.5f ) * _1OverAspect ) * Mathf.Rad2Deg;
m_camera.orthographicSize = m_orthographicSize * _1OverAspect;
}
#if UNITY_EDITOR
private void OnValidate()
{
RefreshCamera();
}
private void OnDisable()
{
UnityEditor.EditorApplication.update -= Update;
}
#endif
}
@cihadturhan
Copy link

Thank you Yasir, this is something I've looking for.
I'm just wondering how I can do the same with cinemachine.

@yasirkula
Copy link
Author

@cihadturhan I unfortunately lack the necessary experience in Cinemachine to answer it.

@agittm
Copy link

agittm commented Oct 24, 2024

Thanks for the script, Yasir. Here's my modified version for cinemachine camera

using Cinemachine;
using UnityEngine;

[ExecuteInEditMode]
[RequireComponent(typeof(CinemachineVirtualCamera))]
public class HorizontalCinemachineCamera : MonoBehaviour
{
    private CinemachineVirtualCamera m_camera;
    private float lastAspect;

#pragma warning disable 0649
    [SerializeField]
    private float m_fieldOfView = 60f;
    public float FieldOfView
    {
        get { return m_fieldOfView; }
        set
        {
            if (m_fieldOfView != value)
            {
                m_fieldOfView = value;
                RefreshCamera();
            }
        }
    }

    [SerializeField]
    private float m_orthographicSize = 5f;
    public float OrthographicSize
    {
        get { return m_orthographicSize; }
        set
        {
            if (m_orthographicSize != value)
            {
                m_orthographicSize = value;
                RefreshCamera();
            }
        }
    }
#pragma warning restore 0649

    private void OnEnable()
    {
        RefreshCamera();

#if UNITY_EDITOR
        UnityEditor.EditorApplication.update -= Update;
        UnityEditor.EditorApplication.update += Update;
#endif
    }

    private void Update()
    {
        float aspect = m_camera.m_Lens.Aspect;
        if (aspect != lastAspect)
            AdjustCamera(aspect);
    }

    public void RefreshCamera()
    {
        if (!m_camera)
            m_camera = GetComponent<CinemachineVirtualCamera>();

        AdjustCamera(m_camera.m_Lens.Aspect);
    }

    private void AdjustCamera(float aspect)
    {
        lastAspect = aspect;

        // Credit: https://forum.unity.com/threads/how-to-calculate-horizontal-field-of-view.16114/#post-2961964
        float _1OverAspect = 1f / aspect;
        m_camera.m_Lens.FieldOfView = 2f * Mathf.Atan(Mathf.Tan(m_fieldOfView * Mathf.Deg2Rad * 0.5f) * _1OverAspect) * Mathf.Rad2Deg;
        m_camera.m_Lens.OrthographicSize = m_orthographicSize * _1OverAspect;
    }

#if UNITY_EDITOR
    private void OnValidate()
    {
        RefreshCamera();
    }

    private void OnDisable()
    {
        UnityEditor.EditorApplication.update -= Update;
    }
#endif
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment