経緯
Unity上のエフェクト素材を他ツールでも活用したかったので作成。
Unityエディター上のSceneビューを定期的にPNG画像としてキャプチャします!背景の透過にも対応!
使い方
- 「Tools > Scene View Capture」からウィンドウを開きます。
- 保存先、FPS、透過設定を調整して「キャプチャ開始」ボタンを押す。
- もう一度ボタンを押すとキャプチャ停止。
- 対応バージョン: Unity6 以降
コード
下記をSceneViewCapture.csで保存し、Editorフォルダに配置!
using UnityEngine; using UnityEditor; using System.IO; public class SceneViewCapture : EditorWindow { private bool capturing = false; private string saveDirectory = "D:\\Downloads\\aaaa"; private int captureCount = 0; private double lastCaptureTime = 0; private double captureInterval = 0.5; private int fps = 30; private bool transparentBackground = false; private Camera tempCamera; [MenuItem("Tools/Scene View Capture")] public static void ShowWindow() { GetWindow<SceneViewCapture>("Scene View Capture"); } private void OnEnable() { EditorApplication.update += OnEditorUpdate; } private void OnDisable() { EditorApplication.update -= OnEditorUpdate; CleanupTempCamera(); } private void OnGUI() { GUILayout.Label("保存先:", EditorStyles.boldLabel); saveDirectory = EditorGUILayout.TextField(saveDirectory); GUILayout.Space(5); GUILayout.Label("FPS:", EditorStyles.boldLabel); fps = EditorGUILayout.IntField(fps); if (fps < 1) fps = 1; captureInterval = 1.0 / fps; GUILayout.Space(5); transparentBackground = EditorGUILayout.Toggle("背景を透過にする", transparentBackground); GUILayout.Space(10); if (!capturing) { if (GUILayout.Button("キャプチャ開始")) { captureCount = 0; capturing = true; lastCaptureTime = EditorApplication.timeSinceStartup; SetupTempCamera(); Debug.Log("キャプチャ開始"); } } else { if (GUILayout.Button("キャプチャ停止")) { capturing = false; CleanupTempCamera(); Debug.Log("キャプチャ停止"); } } } private void OnEditorUpdate() { if (!capturing) return; double currentTime = EditorApplication.timeSinceStartup; if (currentTime - lastCaptureTime >= captureInterval) { lastCaptureTime = currentTime; CaptureSceneView(); } } private void SetupTempCamera() { var sceneView = SceneView.lastActiveSceneView; if (sceneView == null || sceneView.camera == null) return; GameObject camObj = new GameObject("TempSceneCaptureCamera"); tempCamera = camObj.AddComponent<Camera>(); tempCamera.CopyFrom(sceneView.camera); tempCamera.cullingMask = -1; tempCamera.clearFlags = CameraClearFlags.SolidColor; tempCamera.backgroundColor = Color.black; tempCamera.enabled = false; } private void CleanupTempCamera() { if (tempCamera != null) { DestroyImmediate(tempCamera.gameObject); tempCamera = null; } } private void CaptureSceneView() { if (tempCamera == null) return; int width = (int)SceneView.lastActiveSceneView.position.width; int height = (int)SceneView.lastActiveSceneView.position.height; RenderTexture rt = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32); Texture2D texture = new Texture2D(width, height, TextureFormat.ARGB32, false); RenderTexture currentRT = RenderTexture.active; RenderTexture.active = rt; var originalRT = tempCamera.targetTexture; tempCamera.targetTexture = rt; Color originalBackground = tempCamera.backgroundColor; CameraClearFlags originalClearFlags = tempCamera.clearFlags; tempCamera.backgroundColor = Color.black; tempCamera.clearFlags = CameraClearFlags.SolidColor; tempCamera.Render(); texture.ReadPixels(new Rect(0, 0, width, height), 0, 0); Color32[] blackPixels = texture.GetPixels32(); tempCamera.backgroundColor = Color.white; tempCamera.Render(); texture.ReadPixels(new Rect(0, 0, width, height), 0, 0); Color32[] whitePixels = texture.GetPixels32(); for (int i = 0; i < blackPixels.Length; i++) { byte alpha = (byte)(255 - (whitePixels[i].r - blackPixels[i].r)); blackPixels[i].a = alpha; } texture.SetPixels32(blackPixels); texture.Apply(); tempCamera.targetTexture = originalRT; tempCamera.backgroundColor = originalBackground; tempCamera.clearFlags = originalClearFlags; RenderTexture.active = currentRT; DestroyImmediate(rt); if (!Directory.Exists(saveDirectory)) { Directory.CreateDirectory(saveDirectory); } string filename = string.Format("SceneCapture_{0:D4}.png", captureCount); string path = Path.Combine(saveDirectory, filename); byte[] bytes = texture.EncodeToPNG(); File.WriteAllBytes(path, bytes); Debug.Log("保存しました: " + path); captureCount++; AssetDatabase.Refresh(); } }
既出バグ
未発見(募集中!