Sorry, I don’t know how to calculate this. Simply multiplying the aspect ratio by Camera.fieldOfView doesn’t do the trick.
I think you want something like:-
var radAngle = cam.fieldOfView * Mathf.Deg2Rad;
var radHFOV = 2 * Math.Atan(Mathf.Tan(radAngle / 2) * cam.aspect);
var hFOV = Mathf.Rad2Deg * radHFOV;
Thanks!
I figured out something quite similar on my own, but it took me some researching on Wikipedia about trigonometry, because I haven’t really use trig for a decade. However, I didn’t know about camera.aspect, so thanks for pointing me to that!
var vFOVrad : float = camera.fieldOfView * Mathf.Deg2Rad;
var cameraHeightAt1 : float = Mathf.Tan(vFOVrad *.5);
var hFOVrad : float = Mathf.Atan(cameraHeightAt1 * camera.aspect) * 2;
var hFOV : float = hFOVrad * Mathf.Rad2Deg;
You’d think that this would be included for convenience, in the API, if something as simple as camera.aspect is. How should I suggest this to UT?
I think the Report Bug app has an option on the pop-up to send a feature request. UT are more likely to take notice of requests sent like this than Wish List posts, so they say.
If you want to have horizontal fiels of view instead of vertical you need this formula:
camera.fieldOfView = horizontalFieldOfView * (16f/9f) / ((float)camera.pixelWidth / camera.pixelHeight);
6 years later. I find this useful. Took me 10 minutes to understand what you did there. nice 1.
For anyone interested, I wrote a script that you can attach to a gameObject with a camera and it will log the horizontal FOV whenever it is updated. I used Jessy’s formula which seems pretty accurate.
using UnityEngine;
using System.Collections;
[RequireComponent( typeof( Camera ) )]
public class ShowCameraHorizontalFOV : MonoBehaviour {
private Camera cam;
private float horizontalFOV = 0;
private float loggedFOV = 0;
#if UNITY_EDITOR
public void OnDrawGizmos()
{
cam = gameObject.GetComponent<Camera>();
if (cam != null)
{
horizontalFOV = getHorizontalAngle(cam);
if(horizontalFOV != loggedFOV)
{
loggedFOV = horizontalFOV;
logFOV(horizontalFOV);
}
}
}
private float getHorizontalAngle(Camera camera)
{
float vFOVrad = camera.fieldOfView * Mathf.Deg2Rad;
float cameraHeightAt1 = Mathf.Tan(vFOVrad * .5f);
return Mathf.Atan(cameraHeightAt1 * camera.aspect) * 2f * Mathf.Rad2Deg;
}
void OnEnable()
{
if(loggedFOV != 0)
{
logFOV(loggedFOV);
}
}
private void logFOV(float value)
{
Debug.Log(name + "FOV: " + value);
}
#endif
}
Found this thread really useful when I wanted to find a way to fix the horizontal field of view regardless of the aspect ratio of the camera. Here’s the code by way of thanks. Just drop it onto your camera and set your fixed horizontal FOV.
using UnityEngine;
// Lock the cameras horizontal field of view so it will frame the same view in the horizontal regardless of aspect ratio.
[RequireComponent (typeof(Camera))]
public class HorizontalFOVLock : MonoBehaviour {
public float fixedHorizontalFOV = 60;
Camera cam;
void Awake()
{
GetComponent<Camera>().fieldOfView = 2 * Mathf.Atan(Mathf.Tan(fixedHorizontalFOV * Mathf.Deg2Rad * 0.5f) / GetComponent<Camera>().aspect) * Mathf.Rad2Deg;
}
}
If anyone finds this useful, created an solution that keeps the horizontal FOV if device orientation changes to portrait.
Just slap on your camera and define the aspect ratio where it starts keeping stuff horizontally visible.
IE: You like how your fov horizontally looks at 16:9, just use the default HFovOnAspect of 1.777. Job done.
Regular camera variant
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class CameraFovSwitcher : MonoBehaviour {
Camera cam;
Camera Cam { get { if (!cam) cam = GetComponent<Camera>(); return cam; } }
[Range(0.1f, 2)]
[Tooltip("Aspect treshold for switching to horizontal fov calculation")]
public float HFovOnAspect = 1.777f;
float vFov;
float vFovNew;
private void Awake() {
vFov = Cam.fieldOfView;
}
void Update() {
if (Cam.aspect < HFovOnAspect) {
vFovNew = Camera.HorizontalToVerticalFieldOfView(Camera.VerticalToHorizontalFieldOfView(vFov, HFovOnAspect), Cam.aspect);
if (Cam.fieldOfView != vFovNew) {
Cam.fieldOfView = vFovNew;
}
} else if (Cam.fieldOfView != vFov) {
Cam.fieldOfView = vFov;
}
}
}
Cinemachine Virtual Camera variant
using UnityEngine;
using Cinemachine;
[RequireComponent(typeof(CinemachineVirtualCamera))]
public class CMCameraFovSwitcher : MonoBehaviour {
CinemachineVirtualCamera cam;
CinemachineVirtualCamera Cam { get { if (!cam) cam = GetComponent<CinemachineVirtualCamera>(); return cam; } }
[Range(0.1f,2)]
[Tooltip("Aspect treshold for switching to horizontal fov calculation")]
public float HFovOnAspect = 1.777f;
float vFov;
float vFovNew;
private void Awake() {
vFov = Cam.m_Lens.FieldOfView;
}
void Update() {
if (Cam.m_Lens.Aspect < HFovOnAspect) {
vFovNew = Camera.HorizontalToVerticalFieldOfView(Camera.VerticalToHorizontalFieldOfView(vFov, HFovOnAspect), Cam.m_Lens.Aspect);
if (Cam.m_Lens.FieldOfView != vFovNew) {
Cam.m_Lens.FieldOfView = vFovNew;
}
} else if (Cam.m_Lens.FieldOfView != vFov) {
Cam.m_Lens.FieldOfView = vFov;
}
}
}