Created
April 8, 2019 01:05
-
-
Save Chaosed0/11bf2023fc7022cdc2a439434f8ce1a0 to your computer and use it in GitHub Desktop.
A Unity Editor utility for cameras with extremely low FOV.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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