Skip to content

Instantly share code, notes, and snippets.

@iendsl
Last active September 18, 2020 02:21
Show Gist options
  • Save iendsl/bd9371a344969457ae91d544c35f9863 to your computer and use it in GitHub Desktop.
Save iendsl/bd9371a344969457ae91d544c35f9863 to your computer and use it in GitHub Desktop.
A Unity Editor Window for rendering a camera you reference directly. Works with cameras in Prefab Staging scene. Put inside an "Editor" folder, like Assets/Editor.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Experimental.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
//drawing a camera in gui:
//https://answers.unity.com/questions/312472/how-to-change-size-of-camera-preview-in-editor.html
//getting screen res:
//https://answers.unity.com/questions/560518/get-game-view-window-current-width-height-in-scrip.html
namespace Turnfollow.Utilities
{
public class DirectCameraWindow : EditorWindow
{
private Camera _camera;
private Vector2 _cameraRenderSize = new Vector2(1080, 1920);
//set these to skybox if you use skybox
private CameraClearFlags _clearFlags = CameraClearFlags.SolidColor;
private RenderTexture _renderTexture;
private const float CONTROL_AREA_HEIGHT = 80;
[MenuItem("Turnfollow/Direct Camera Window")]
private static void Init()
{
DirectCameraWindow window = GetWindow<DirectCameraWindow>();
window.titleContent = new GUIContent("Direct Camera Window");
window.autoRepaintOnSceneChange = true;
window.Populate();
window.Show();
}
private void Populate()
{
RefreshRenderSize();
RefreshTexture();
}
private void RefreshRenderSize()
{
string[] screenRes = UnityStats.screenRes.Split('x');
_cameraRenderSize = new Vector2(int.Parse(screenRes[0]), int.Parse(screenRes[1]));
}
private void RefreshTexture()
{
_renderTexture = new RenderTexture((int)_cameraRenderSize.x, (int)_cameraRenderSize.y, 24);
}
private void Update()
{
if (_camera != null)
{
Scene previousScene = _camera.scene;
CameraClearFlags previousClearFlags = _camera.clearFlags;
RenderTexture previousTexture = _camera.targetTexture;
//tells the camera to render the prefab scene if it's in one
if (PrefabUtility.IsPartOfAnyPrefab(_camera))
{
PrefabStage stage = PrefabStageUtility.GetPrefabStage(_camera.gameObject);
if (stage != null)
{
_camera.scene = stage.scene;
}
}
//i use clear depth for my cameras so i want to override the clearflags
_camera.clearFlags = _clearFlags;
_camera.targetTexture = _renderTexture;
_camera.Render();
//reset camera values to what they were
_camera.targetTexture = previousTexture;
_camera.scene = previousScene;
_camera.clearFlags = previousClearFlags;
}
}
private void OnDestroy()
{
if(_renderTexture != null)
{
_renderTexture.DiscardContents();
_renderTexture = null;
}
}
private void OnGUI()
{
//inspector selector for the camera to draw
_camera = EditorGUILayout.ObjectField(_camera, typeof(Camera), true) as Camera;
EditorGUI.BeginChangeCheck();
_cameraRenderSize = EditorGUILayout.Vector2Field("Camera Render Size", _cameraRenderSize);
if (EditorGUI.EndChangeCheck())
{
//refresh the render texture to the new dimensions
RefreshTexture();
}
if (_renderTexture != null)
{
//use the rect of the window but bump it down a little for controls
Rect cameraTextureRect = new Rect(position);
cameraTextureRect.x = 0;
cameraTextureRect.y = CONTROL_AREA_HEIGHT;
float windowWidth = cameraTextureRect.width;
float windowHeight = cameraTextureRect.height - cameraTextureRect.y;
float camRatio = _cameraRenderSize.x / _cameraRenderSize.y;
float windowRatio = windowWidth / windowHeight;
//fit the texture into the window at correct aspect
if (windowRatio < camRatio)
{
float ratio = windowWidth / _cameraRenderSize.x;
cameraTextureRect.height = _cameraRenderSize.y * ratio;
}
else
{
float ratio = windowHeight / _cameraRenderSize.y;
cameraTextureRect.width = _cameraRenderSize.x * ratio;
}
EditorGUI.DrawTextureTransparent(cameraTextureRect, _renderTexture);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment