Last active
January 25, 2022 13:05
-
-
Save giacomelli/ad9d4dcdb702d2d1edf0663628ca9608 to your computer and use it in GitHub Desktop.
#unitytips: Scene Preview Window - http://diegogiacomelli.com.br/unitytips-scene-preview-window
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; | |
/// <summary> | |
/// Scene preview data. | |
/// http://diegogiacomelli.com.br/unitytips-scene-preview-window | |
/// </summary> | |
public class ScenePreviewData | |
{ | |
Texture2D _texture; | |
public ScenePreviewData(string scenePath, string texturePath) | |
{ | |
ScenePath = scenePath; | |
TexturePath = texturePath; | |
} | |
public string ScenePath { get; private set; } | |
public string TexturePath { get; private set; } | |
public Texture2D Texture | |
{ | |
get | |
{ | |
return _texture ?? (_texture = AssetDatabase.LoadAssetAtPath<Texture2D>(TexturePath)); | |
} | |
} | |
} |
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 System; | |
using System.IO; | |
using System.Reflection; | |
using UnityEngine; | |
using UnityEditor; | |
using UnityEngine.SceneManagement; | |
/// <summary> | |
/// Scene preview screenshot. | |
/// http://diegogiacomelli.com.br/unitytips-scene-preview-window | |
/// </summary> | |
public static class ScenePreviewScreenshot | |
{ | |
public static bool Capture(bool force = true) | |
{ | |
var previewPath = ScenePreviewUtility.GetPreviewPath(SceneManager.GetActiveScene().name); | |
if (force || !File.Exists(previewPath)) | |
{ | |
var cam = Camera.main; | |
if (cam == null) | |
{ | |
cam = UnityEngine.Object.FindObjectOfType<Camera>(); | |
if (cam == null) | |
{ | |
Debug.LogError("There is no Camera on the scene. Cannot take a screenshot."); | |
return false; | |
} | |
} | |
var size = GetGameWindowSize(); | |
var width = (int)size.x; | |
var height = (int)size.y; | |
cam.targetTexture = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32); | |
RenderTexture.active = cam.targetTexture; | |
cam.Render(); | |
var tex = new Texture2D(width, height, TextureFormat.RGB24, false); | |
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0); | |
cam.targetTexture = null; | |
tex.Apply(); | |
byte[] bytes = tex.EncodeToPNG(); | |
File.WriteAllBytes(previewPath, bytes); | |
AssetDatabase.ImportAsset(previewPath); | |
return true; | |
} | |
return false; | |
} | |
// http://answers.unity.com/answers/192818/view.html | |
static Vector2 GetGameWindowSize() | |
{ | |
Type T = Type.GetType("UnityEditor.GameView,UnityEditor"); | |
MethodInfo GetSizeOfMainGameView = T.GetMethod("GetSizeOfMainGameView", BindingFlags.NonPublic | BindingFlags.Static); | |
return (Vector2) GetSizeOfMainGameView.Invoke(null, null); | |
} | |
} |
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 System; | |
using System.IO; | |
using System.Linq; | |
using System.Runtime.CompilerServices; | |
using UnityEngine; | |
using UnityEditor; | |
using UnityEngine.SceneManagement; | |
/// <summary> | |
/// Scene preview utility. | |
/// http://diegogiacomelli.com.br/unitytips-scene-preview-window | |
/// </summary> | |
public static class ScenePreviewUtility | |
{ | |
public static ScenePreviewData[] Data { get; private set; } = new ScenePreviewData[0]; | |
public static bool ShowCaptureScreenshotButton { get; private set; } | |
public static void RefreshTextures(ScenePreviewWindow window) | |
{ | |
// Get the selected SceneAsset previews. | |
var previewsPaths = Selection.objects | |
.Where(asset => asset is SceneAsset) | |
.Select(sceneAsset => new ScenePreviewData(AssetDatabase.GetAssetPath(sceneAsset), GetPreviewPath(((SceneAsset)sceneAsset).name))) | |
.OrderBy(n => n.TexturePath) | |
.ToList(); | |
if (previewsPaths.Count == 1) | |
window.ShowTab(); | |
// If there no SceneAsset selected, then show the current scene preview. | |
var activeScene = SceneManager.GetActiveScene(); | |
var activeScenePreviewPath = GetPreviewPath(activeScene.name); | |
if (previewsPaths.Count == 0) | |
previewsPaths.Add(new ScenePreviewData(activeScene.path, activeScenePreviewPath)); | |
ShowCaptureScreenshotButton = previewsPaths.Count == 1 && previewsPaths[0].TexturePath == activeScenePreviewPath; | |
// Loads the previews textures. | |
Data = previewsPaths | |
.Distinct() | |
.Where(item => item.Texture != null) | |
.ToArray(); | |
window.Repaint(); | |
} | |
public static string GetPreviewPath(string sceneName = null) | |
{ | |
var folder = GetPreviewFolderRootedPath().Replace(Application.dataPath, string.Empty); | |
folder = $"Assets{folder}"; | |
return String.IsNullOrEmpty(sceneName) | |
? folder | |
: Path.Combine(folder, $"{sceneName}.png"); | |
} | |
private static string GetPreviewFolderRootedPath([CallerFilePath] string callerFilePath = null) | |
{ | |
var folder = Path.Combine(Path.GetDirectoryName(callerFilePath), "Previews"); | |
if (!Directory.Exists(folder)) | |
Directory.CreateDirectory(folder); | |
return folder.Replace(@"\", "/"); | |
} | |
} |
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 UnityEngine.SceneManagement; | |
using UnityEditor.SceneManagement; | |
/// <summary> | |
/// Scene preview window. | |
/// http://diegogiacomelli.com.br/unitytips-scene-preview-window | |
/// </summary> | |
public class ScenePreviewWindow : EditorWindow | |
{ | |
const float EditorMargin = 1; | |
const float PreviewMargin = 1; | |
const int Columns = 2; | |
const int CaptureScreenshotButtonHeight = 30; | |
const float SecondsToAutoCaptureScreenshot = 10f; | |
static GUIStyle _buttonStyle = new GUIStyle(); | |
static ScenePreviewWindow _instance; | |
[MenuItem("Window/Scene Preview")] | |
public static void ShowWindow() | |
{ | |
_instance = EditorWindow.GetWindow<ScenePreviewWindow>("Scene Preview"); | |
} | |
[InitializeOnLoadMethod] | |
static void Initialize() | |
{ | |
Selection.selectionChanged += HandleSelectionChange; | |
EditorApplication.playModeStateChanged += HandlePlayModeStateChanged; | |
EditorSceneManager.sceneOpened += HandleEditorSceneManagerSceneOpened; | |
} | |
void OnEnable() | |
{ | |
_instance = this; | |
_buttonStyle.normal.background = null; | |
} | |
void OnDestroy() | |
{ | |
Selection.selectionChanged -= HandleSelectionChange; | |
EditorApplication.playModeStateChanged -= HandlePlayModeStateChanged; | |
EditorSceneManager.sceneOpened -= HandleEditorSceneManagerSceneOpened; | |
_instance = null; | |
} | |
static void HandleSelectionChange() | |
{ | |
if (_instance != null) | |
{ | |
ScenePreviewUtility.RefreshTextures(_instance); | |
} | |
} | |
static void HandlePlayModeStateChanged(PlayModeStateChange playMode) | |
{ | |
if (playMode == PlayModeStateChange.EnteredPlayMode && _instance != null) | |
{ | |
EditorApplication.update += HandleUpdate; | |
HandleSelectionChange(); | |
} | |
} | |
static void HandleEditorSceneManagerSceneOpened(Scene scene, OpenSceneMode mode) | |
{ | |
HandleSelectionChange(); | |
} | |
static void HandleUpdate() | |
{ | |
if(Time.timeSinceLevelLoad > SecondsToAutoCaptureScreenshot) | |
{ | |
EditorApplication.update -= HandleUpdate; | |
if (_instance != null && ScenePreviewScreenshot.Capture(false)) | |
ScenePreviewUtility.RefreshTextures(_instance); | |
} | |
} | |
void OnGUI() | |
{ | |
var rect = new Rect(EditorMargin, EditorMargin, Screen.width, position.height - EditorMargin * 2 - PreviewMargin - CaptureScreenshotButtonHeight - EditorMargin); | |
var data = ScenePreviewUtility.Data; | |
if (data.Length > 0) | |
{ | |
var previewsCount = data.Length; | |
var height = (position.height - EditorMargin * 2 - (PreviewMargin * previewsCount) - CaptureScreenshotButtonHeight) / previewsCount; | |
var index = 0; | |
foreach (var item in data) | |
{ | |
rect = new Rect(EditorMargin, index * (height + PreviewMargin), position.width, height); | |
if (GUI.Button(rect, string.Empty, _buttonStyle)) | |
{ | |
EditorSceneManager.OpenScene(item.ScenePath); | |
} | |
GUI.DrawTexture(rect, item.Texture, ScaleMode.ScaleToFit); | |
index++; | |
} | |
} | |
if (ScenePreviewUtility.ShowCaptureScreenshotButton && | |
GUI.Button(new Rect(EditorMargin, rect.yMax + PreviewMargin, position.width - (EditorMargin * 2), CaptureScreenshotButtonHeight), "Capture screenshot")) | |
{ | |
ScenePreviewScreenshot.Capture(); | |
ScenePreviewUtility.RefreshTextures(this); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment