Skip to content

Instantly share code, notes, and snippets.

@Chaosed0
Created April 8, 2019 01:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Chaosed0/11bf2023fc7022cdc2a439434f8ce1a0 to your computer and use it in GitHub Desktop.
Save Chaosed0/11bf2023fc7022cdc2a439434f8ce1a0 to your computer and use it in GitHub Desktop.
A Unity Editor utility for cameras with extremely low FOV.
using UnityEngine;
using UnityEditor;
using Cinemachine;
using System.Collections.Generic;
// To make this work, create an empty MonoBehaviour called "LowFovCameraUtility".
// Then, attach that script to your Cinemachine virtual cameras.
// If you don't want to use Cinemachine virtual cameras this script should work too,
// you'll just need to modify the components and variable names.
[CustomEditor(typeof(LowFovCameraUtility))]
public class LowFovCameraUtilityEditor : Editor
{
// This is the amount of depth/height the near/far plane will allow for when automatically set.
public static float nearPlaneFudge = 30f;
public static float farPlaneFudge = 30f;
private CinemachineVirtualCamera camera;
private SerializedObject serializedCinemachineVcam;
private SerializedProperty cinemachineVcamNearClipProperty;
private SerializedProperty cinemachineVcamFarClipProperty;
private void OnEnable()
{
LowFovCameraUtility target = this.target as LowFovCameraUtility;
camera = target.GetComponent<CinemachineVirtualCamera>();
if (camera == null)
{
Debug.LogError("No camera attached", target);
}
serializedCinemachineVcam = new SerializedObject(camera);
cinemachineVcamNearClipProperty = serializedCinemachineVcam.FindProperty("m_Lens").FindPropertyRelative("NearClipPlane");
cinemachineVcamFarClipProperty = serializedCinemachineVcam.FindProperty("m_Lens").FindPropertyRelative("FarClipPlane");
}
private void OnSceneGUI()
{
if (target == null)
{
return;
}
if (camera == null)
{
Debug.LogError("No camera attached", target);
return;
}
Vector3 handlePosition = camera.transform.position + camera.transform.forward * camera.m_Lens.NearClipPlane;
Vector3 newPosition = handlePosition;
Quaternion newRotation = camera.transform.rotation;
switch (Tools.current)
{
case Tool.Move:
newPosition = Handles.DoPositionHandle(handlePosition, Tools.handleRotation);
if ((newPosition - handlePosition).sqrMagnitude > Mathf.Epsilon)
{
Undo.RecordObject(camera.transform, "Low Fov Camera Utility Handle Move");
camera.transform.position += (newPosition - handlePosition);
}
break;
case Tool.Rotate:
newRotation = Handles.DoRotationHandle(camera.transform.rotation, handlePosition);
if (Quaternion.Angle(newRotation, camera.transform.rotation) > Mathf.Epsilon)
{
Undo.RecordObject(camera.transform, "Low Fov Camera Utility Handle Rotate");
camera.transform.rotation = newRotation;
camera.transform.position = handlePosition - newRotation * (Vector3.forward * Vector3.Distance(camera.transform.position, handlePosition));
}
break;
default:
break;
}
}
public override void OnInspectorGUI()
{
serializedObject.Update();
DrawDefaultInspector();
if (GUILayout.Button("Auto-resize clip planes"))
{
SetCameraProps(target as LowFovCameraUtility);
serializedCinemachineVcam.ApplyModifiedProperties();
}
serializedObject.ApplyModifiedProperties();
}
public void SetCameraProps(LowFovCameraUtility target)
{
float theta = Vector3.Angle(camera.transform.forward, Vector3.down);
float y = camera.transform.position.y;
float topPlaneDistanceToZero = (y + farPlaneFudge) / Mathf.Cos((theta + camera.m_Lens.FieldOfView / 2f) * Mathf.Deg2Rad);
float farPlaneDistance = Mathf.Cos(camera.m_Lens.FieldOfView / 2f * Mathf.Deg2Rad) * topPlaneDistanceToZero;
float bottomPlaneDistanceToZero = (y - nearPlaneFudge) / Mathf.Cos((theta - camera.m_Lens.FieldOfView / 2f) * Mathf.Deg2Rad);
float nearPlaneDistance = Mathf.Cos(camera.m_Lens.FieldOfView / 2f * Mathf.Deg2Rad) * bottomPlaneDistanceToZero;
cinemachineVcamNearClipProperty.floatValue = nearPlaneDistance;
cinemachineVcamFarClipProperty.floatValue = farPlaneDistance;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment