Skip to content

Instantly share code, notes, and snippets.

@JohannesMP
Last active March 11, 2021 03:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JohannesMP/265c9d8a4c2447c01a8ccf785fad14f8 to your computer and use it in GitHub Desktop.
Save JohannesMP/265c9d8a4c2447c01a8ccf785fad14f8 to your computer and use it in GitHub Desktop.
[Unity3D] Use the scene view camera to easily control a camera in editor.
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
[ExecuteAlways]
public class ControlCameraWithSceneCam : MonoBehaviour
{
private void OnValidate()
{
bool haveBackupState = _targetCamBackupState != null && _targetCamBackupState.camera != null;
// Field was just cleared
if (targetCamera == null && haveBackupState)
{
ReleaseCameraControl();
}
if (targetCamera != null)
{
// Field just set, was null before
if (!haveBackupState)
{
SetCameraControl();
}
// field just set, was a different camera
else if (targetCamera != _targetCamBackupState.camera)
{
SetCameraControl();
}
}
}
[Header("If set will update this camera using scene view camera")]
public Camera targetCamera;
// Used to revert camera state after we're done controlling it
private CameraState _targetCamBackupState;
private void OnEnable()
{
EditorApplication.update += CameraUpdateCheck;
SetCameraControl();
}
private void OnDisable()
{
EditorApplication.update -= CameraUpdateCheck;
ReleaseCameraControl();
}
private void SetCameraControl()
{
if (_targetCamBackupState != null)
{
ReleaseCameraControl();
}
if (targetCamera != null)
{
_targetCamBackupState = new CameraState(targetCamera);
targetCamera.transform.hideFlags |= HideFlags.NotEditable;
}
}
private void ReleaseCameraControl()
{
if (_targetCamBackupState != null)
{
_targetCamBackupState.Revert();
_targetCamBackupState = null;
}
}
private readonly CameraState _scratchTargetState = new CameraState();
private readonly CameraState _scratchSourceState = new CameraState();
private void CameraUpdateCheck()
{
if (targetCamera == null ||
SceneView.lastActiveSceneView == null ||
SceneView.lastActiveSceneView.camera == null)
{
return;
}
Camera sourceCamera = SceneView.lastActiveSceneView.camera;
_scratchTargetState.Set(targetCamera);
_scratchSourceState.Set(sourceCamera);
if (_scratchTargetState.Apply(_scratchSourceState))
{
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
}
}
/// <summary>
/// Helper class to manage camera state
/// </summary>
private class CameraState
{
public Camera camera;
public Vector3 localPosition;
public Quaternion localRotation;
public float fieldOfView;
public bool orthographic;
public float orthographicSize;
public HideFlags hideFlags;
public CameraState(Camera cam = null)
{
if (cam != null)
{
Set(cam);
}
}
public void Set(Camera cam)
{
camera = cam;
localPosition = cam.transform.localPosition;
localRotation = cam.transform.localRotation;
fieldOfView = cam.fieldOfView;
orthographic = cam.orthographic;
orthographicSize = cam.orthographicSize;
hideFlags = cam.transform.hideFlags;
}
public void Revert()
{
if (camera == null) return;
camera.transform.localPosition = localPosition;
camera.transform.localRotation = localRotation;
camera.fieldOfView = camera.fieldOfView;
camera.orthographic = camera.orthographic;
camera.orthographicSize = camera.orthographicSize;
camera.transform.hideFlags = hideFlags;
}
public bool Apply(CameraState source)
{
if (camera == null || source?.camera == null) return false;
Transform targetTransform = camera.transform;
Transform sourceTransform = source.camera.transform;
bool haveChange =
targetTransform.position != sourceTransform.position ||
targetTransform.rotation != sourceTransform.rotation ||
camera.orthographic != source.camera.orthographic ||
Mathf.Abs(camera.fieldOfView - source.camera.fieldOfView) > Mathf.Epsilon ||
Mathf.Abs(camera.orthographicSize - source.camera.orthographicSize) > Mathf.Epsilon;
if (haveChange)
{
targetTransform.SetPositionAndRotation(sourceTransform.position, sourceTransform.rotation);
camera.orthographic = source.camera.orthographic;
camera.fieldOfView = source.camera.fieldOfView;
camera.orthographicSize = source.camera.orthographicSize;
}
return haveChange;
}
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment