717 lines
25 KiB
C#
717 lines
25 KiB
C#
using System.IO;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
namespace Streamingle.Background.Editor
|
|
{
|
|
/// <summary>
|
|
/// 배경 씬 썸네일 캡처 도구
|
|
/// </summary>
|
|
public class BackgroundThumbnailCapture : EditorWindow
|
|
{
|
|
// 16:9 기본값
|
|
private const int DEFAULT_WIDTH = 1920;
|
|
private const int DEFAULT_HEIGHT = 1080;
|
|
|
|
private Camera _selectedCamera;
|
|
private int _width = DEFAULT_WIDTH;
|
|
private int _height = DEFAULT_HEIGHT;
|
|
|
|
private BackgroundSyncSettings _syncSettings;
|
|
private string _savePath;
|
|
private string _fileName;
|
|
private bool _useSceneCamera = true;
|
|
private Texture2D _previewTexture;
|
|
|
|
private BackgroundSceneDatabase _database;
|
|
private BackgroundSceneInfo _currentSceneInfo;
|
|
|
|
[MenuItem("Streamingle/Capture Background Thumbnail %#t")]
|
|
public static void ShowWindow()
|
|
{
|
|
var window = GetWindow<BackgroundThumbnailCapture>("썸네일 캡처");
|
|
window.minSize = new Vector2(350, 500);
|
|
window.Show();
|
|
window.Initialize();
|
|
}
|
|
|
|
private void Initialize()
|
|
{
|
|
// 데이터베이스 로드
|
|
_database = AssetDatabase.LoadAssetAtPath<BackgroundSceneDatabase>(
|
|
"Assets/Resources/Settings/BackgroundSceneDatabase.asset");
|
|
|
|
// 동기화 설정 로드
|
|
_syncSettings = AssetDatabase.LoadAssetAtPath<BackgroundSyncSettings>(
|
|
"Assets/Resources/Settings/BackgroundSyncSettings.asset");
|
|
|
|
// 설정에서 해상도 가져오기
|
|
if (_syncSettings != null)
|
|
{
|
|
_width = _syncSettings.thumbnailWidth;
|
|
_height = _syncSettings.thumbnailHeight;
|
|
}
|
|
|
|
// 현재 로드된 배경 씬 찾기
|
|
FindCurrentBackgroundScene();
|
|
|
|
// 카메라 찾기
|
|
FindSceneCamera();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_previewTexture != null)
|
|
{
|
|
DestroyImmediate(_previewTexture);
|
|
}
|
|
}
|
|
|
|
private void FindCurrentBackgroundScene()
|
|
{
|
|
_currentSceneInfo = null;
|
|
_savePath = "";
|
|
_fileName = "";
|
|
|
|
if (_database == null) return;
|
|
|
|
const string BACKGROUND_PATH = "Assets/ResourcesData/Background";
|
|
|
|
// 현재 로드된 씬들 중 배경 씬 찾기
|
|
for (int i = 0; i < SceneManager.sceneCount; i++)
|
|
{
|
|
var scene = SceneManager.GetSceneAt(i);
|
|
if (string.IsNullOrEmpty(scene.path)) continue;
|
|
|
|
// 데이터베이스에서 찾기
|
|
var sceneInfo = _database.FindByPath(scene.path);
|
|
|
|
if (sceneInfo != null)
|
|
{
|
|
_currentSceneInfo = sceneInfo;
|
|
_savePath = Path.GetDirectoryName(sceneInfo.scenePath);
|
|
_fileName = sceneInfo.sceneName;
|
|
return;
|
|
}
|
|
|
|
// 데이터베이스에 없지만 Background 폴더에 있는 씬인 경우
|
|
// 데이터베이스를 갱신하고 다시 찾기
|
|
if (scene.path.Replace("\\", "/").Contains(BACKGROUND_PATH))
|
|
{
|
|
// 데이터베이스 갱신
|
|
RefreshDatabaseFromLoaderWindow();
|
|
|
|
// 다시 찾기
|
|
sceneInfo = _database.FindByPath(scene.path);
|
|
if (sceneInfo != null)
|
|
{
|
|
_currentSceneInfo = sceneInfo;
|
|
_savePath = Path.GetDirectoryName(sceneInfo.scenePath);
|
|
_fileName = sceneInfo.sceneName;
|
|
return;
|
|
}
|
|
|
|
// 여전히 없으면 수동으로 정보 설정
|
|
string scenePath = scene.path.Replace("\\", "/");
|
|
_savePath = Path.GetDirectoryName(scenePath);
|
|
_fileName = scene.name;
|
|
|
|
// 카테고리 추출 (폴더명)
|
|
string relativePath = scenePath.Substring(BACKGROUND_PATH.Length + 1);
|
|
string categoryName = relativePath.Split('/')[0];
|
|
|
|
// 새 씬 정보 생성 및 데이터베이스에 추가
|
|
_currentSceneInfo = new BackgroundSceneInfo
|
|
{
|
|
sceneName = scene.name,
|
|
scenePath = scenePath,
|
|
categoryName = categoryName,
|
|
thumbnailPath = ""
|
|
};
|
|
|
|
_database.scenes.Add(_currentSceneInfo);
|
|
EditorUtility.SetDirty(_database);
|
|
AssetDatabase.SaveAssets();
|
|
|
|
UnityEngine.Debug.Log($"새 배경 씬이 데이터베이스에 추가됨: {scene.name}");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 배경 씬을 못 찾으면 활성 씬 사용
|
|
var activeScene = SceneManager.GetActiveScene();
|
|
if (!string.IsNullOrEmpty(activeScene.path))
|
|
{
|
|
_savePath = Path.GetDirectoryName(activeScene.path);
|
|
_fileName = activeScene.name;
|
|
}
|
|
}
|
|
|
|
private void RefreshDatabaseFromLoaderWindow()
|
|
{
|
|
// BackgroundSceneLoaderWindow가 열려있으면 RefreshSceneList 호출
|
|
var loaderWindow = GetWindow<BackgroundSceneLoaderWindow>(false, null, false);
|
|
if (loaderWindow != null)
|
|
{
|
|
// 리플렉션으로 private 메서드 호출
|
|
var refreshMethod = typeof(BackgroundSceneLoaderWindow).GetMethod("RefreshSceneList",
|
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
|
if (refreshMethod != null)
|
|
{
|
|
refreshMethod.Invoke(loaderWindow, null);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 윈도우가 없으면 직접 갱신
|
|
RefreshSceneListDirectly();
|
|
}
|
|
|
|
// 데이터베이스 다시 로드
|
|
_database = AssetDatabase.LoadAssetAtPath<BackgroundSceneDatabase>(
|
|
"Assets/Resources/Settings/BackgroundSceneDatabase.asset");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scene 또는 scene 폴더를 실제 대소문자로 찾기
|
|
/// </summary>
|
|
private string FindSceneFolderWithCorrectCase(string parentFolder)
|
|
{
|
|
var subDirs = Directory.GetDirectories(parentFolder);
|
|
foreach (var dir in subDirs)
|
|
{
|
|
string dirName = Path.GetFileName(dir);
|
|
if (string.Equals(dirName, "Scene", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return dir;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void RefreshSceneListDirectly()
|
|
{
|
|
if (_database == null) return;
|
|
|
|
const string BACKGROUND_PATH = "Assets/ResourcesData/Background";
|
|
|
|
_database.scenes.Clear();
|
|
|
|
if (!Directory.Exists(BACKGROUND_PATH))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Background 하위 폴더들 검색
|
|
var backgroundFolders = Directory.GetDirectories(BACKGROUND_PATH);
|
|
|
|
foreach (var folderPath in backgroundFolders)
|
|
{
|
|
string folderName = Path.GetFileName(folderPath);
|
|
string sceneFolderPath = FindSceneFolderWithCorrectCase(folderPath);
|
|
|
|
if (sceneFolderPath == null)
|
|
{
|
|
sceneFolderPath = folderPath;
|
|
}
|
|
|
|
// .unity 파일 검색 (재귀적으로)
|
|
var sceneFiles = Directory.GetFiles(sceneFolderPath, "*.unity", SearchOption.AllDirectories);
|
|
|
|
foreach (var sceneFile in sceneFiles)
|
|
{
|
|
if (sceneFile.Contains("SkyBox")) continue;
|
|
|
|
string assetPath = sceneFile.Replace("\\", "/");
|
|
string sceneName = Path.GetFileNameWithoutExtension(sceneFile);
|
|
string sceneDir = Path.GetDirectoryName(sceneFile);
|
|
|
|
string thumbnailPath = FindThumbnail(sceneDir, sceneName);
|
|
|
|
var sceneInfo = new BackgroundSceneInfo
|
|
{
|
|
sceneName = sceneName,
|
|
scenePath = assetPath,
|
|
categoryName = folderName,
|
|
thumbnailPath = thumbnailPath
|
|
};
|
|
|
|
_database.scenes.Add(sceneInfo);
|
|
}
|
|
}
|
|
|
|
EditorUtility.SetDirty(_database);
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
|
|
private string FindThumbnail(string directory, string sceneName)
|
|
{
|
|
string[] extensions = { ".png", ".jpg", ".jpeg" };
|
|
|
|
foreach (var ext in extensions)
|
|
{
|
|
string thumbnailPath = Path.Combine(directory, sceneName + ext);
|
|
if (File.Exists(thumbnailPath))
|
|
{
|
|
return thumbnailPath.Replace("\\", "/");
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void FindSceneCamera()
|
|
{
|
|
_selectedCamera = null;
|
|
|
|
// 1. 씬에서 Main Camera 찾기
|
|
_selectedCamera = Camera.main;
|
|
|
|
// 2. Main Camera가 없으면 아무 카메라나 찾기
|
|
if (_selectedCamera == null)
|
|
{
|
|
var cameras = FindObjectsByType<Camera>(FindObjectsSortMode.None);
|
|
if (cameras.Length > 0)
|
|
{
|
|
_selectedCamera = cameras[0];
|
|
}
|
|
}
|
|
|
|
// 3. Scene View 카메라 사용 옵션
|
|
if (_selectedCamera == null)
|
|
{
|
|
_useSceneCamera = true;
|
|
}
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
EditorGUILayout.Space(10);
|
|
EditorGUILayout.LabelField("배경 썸네일 캡처", EditorStyles.boldLabel);
|
|
EditorGUILayout.Space(5);
|
|
|
|
// 현재 씬 정보
|
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
|
EditorGUILayout.BeginHorizontal();
|
|
if (_currentSceneInfo != null)
|
|
{
|
|
EditorGUILayout.BeginVertical();
|
|
EditorGUILayout.LabelField("현재 배경 씬:", _currentSceneInfo.sceneName);
|
|
EditorGUILayout.LabelField("카테고리:", _currentSceneInfo.categoryName);
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
else
|
|
{
|
|
EditorGUILayout.BeginVertical();
|
|
EditorGUILayout.LabelField("배경 씬을 찾을 수 없습니다.", EditorStyles.miniLabel);
|
|
EditorGUILayout.LabelField("배경 씬을 먼저 로드하세요.");
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
if (GUILayout.Button("새로고침", GUILayout.Width(70), GUILayout.Height(35)))
|
|
{
|
|
Initialize();
|
|
UnityEngine.Debug.Log("씬 정보가 새로고침되었습니다.");
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
EditorGUILayout.EndVertical();
|
|
|
|
EditorGUILayout.Space(10);
|
|
|
|
// 카메라 선택
|
|
EditorGUILayout.LabelField("카메라 설정", EditorStyles.boldLabel);
|
|
|
|
_useSceneCamera = EditorGUILayout.Toggle("Scene View 카메라 사용", _useSceneCamera);
|
|
|
|
if (!_useSceneCamera)
|
|
{
|
|
_selectedCamera = (Camera)EditorGUILayout.ObjectField("카메라", _selectedCamera, typeof(Camera), true);
|
|
|
|
// 카메라 목록 버튼
|
|
if (GUILayout.Button("씬에서 카메라 찾기"))
|
|
{
|
|
ShowCameraMenu();
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.Space(10);
|
|
|
|
// 해상도 설정
|
|
EditorGUILayout.LabelField("해상도 설정", EditorStyles.boldLabel);
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
_width = EditorGUILayout.IntField("너비", _width);
|
|
_height = EditorGUILayout.IntField("높이", _height);
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
if (GUILayout.Button("1920x1080 (권장)")) { _width = 1920; _height = 1080; }
|
|
if (GUILayout.Button("1280x720")) { _width = 1280; _height = 720; }
|
|
if (GUILayout.Button("960x540")) { _width = 960; _height = 540; }
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
EditorGUILayout.HelpBox("16:9 비율 썸네일이 권장됩니다.\n에디터에서는 1:1로 크롭되어 표시되고, 웹사이트에는 16:9 원본이 사용됩니다.", MessageType.Info);
|
|
|
|
EditorGUILayout.Space(10);
|
|
|
|
// 저장 경로
|
|
EditorGUILayout.LabelField("저장 설정", EditorStyles.boldLabel);
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
_savePath = EditorGUILayout.TextField("저장 경로", _savePath);
|
|
if (GUILayout.Button("...", GUILayout.Width(30)))
|
|
{
|
|
string path = EditorUtility.OpenFolderPanel("저장 폴더 선택", _savePath, "");
|
|
if (!string.IsNullOrEmpty(path))
|
|
{
|
|
// Assets 폴더 기준 상대 경로로 변환
|
|
if (path.StartsWith(Application.dataPath))
|
|
{
|
|
_savePath = "Assets" + path.Substring(Application.dataPath.Length);
|
|
}
|
|
else
|
|
{
|
|
_savePath = path;
|
|
}
|
|
}
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
_fileName = EditorGUILayout.TextField("파일 이름", _fileName);
|
|
|
|
EditorGUILayout.LabelField($"저장 위치: {_savePath}/{_fileName}.png", EditorStyles.miniLabel);
|
|
|
|
EditorGUILayout.Space(10);
|
|
|
|
// 프리뷰
|
|
EditorGUILayout.LabelField("프리뷰", EditorStyles.boldLabel);
|
|
|
|
if (GUILayout.Button("프리뷰 갱신", GUILayout.Height(25)))
|
|
{
|
|
CapturePreview();
|
|
}
|
|
|
|
if (_previewTexture != null)
|
|
{
|
|
float previewHeight = position.width * _previewTexture.height / _previewTexture.width;
|
|
var previewRect = GUILayoutUtility.GetRect(position.width - 20, Mathf.Min(previewHeight, 300));
|
|
GUI.DrawTexture(previewRect, _previewTexture, ScaleMode.ScaleToFit);
|
|
}
|
|
|
|
EditorGUILayout.Space(10);
|
|
|
|
// 캡처 버튼
|
|
GUI.enabled = !string.IsNullOrEmpty(_savePath) && !string.IsNullOrEmpty(_fileName);
|
|
|
|
GUI.backgroundColor = new Color(0.3f, 0.8f, 0.3f);
|
|
if (GUILayout.Button("썸네일 캡처 및 저장", GUILayout.Height(40)))
|
|
{
|
|
CaptureAndSave();
|
|
}
|
|
GUI.backgroundColor = Color.white;
|
|
|
|
GUI.enabled = true;
|
|
|
|
// 모든 배경 씬 썸네일 일괄 캡처
|
|
EditorGUILayout.Space(10);
|
|
EditorGUILayout.LabelField("일괄 캡처", EditorStyles.boldLabel);
|
|
|
|
if (GUILayout.Button("모든 배경 씬 썸네일 캡처", GUILayout.Height(30)))
|
|
{
|
|
CaptureAllBackgroundScenes();
|
|
}
|
|
|
|
// 썸네일 새로고침
|
|
EditorGUILayout.Space(10);
|
|
if (GUILayout.Button("배경 로더 썸네일 새로고침", GUILayout.Height(25)))
|
|
{
|
|
var loaderWindow = GetWindow<BackgroundSceneLoaderWindow>(false, null, false);
|
|
if (loaderWindow != null)
|
|
{
|
|
loaderWindow.RefreshAllThumbnails();
|
|
UnityEngine.Debug.Log("썸네일 캐시가 새로고침되었습니다.");
|
|
}
|
|
else
|
|
{
|
|
UnityEngine.Debug.LogWarning("배경 씬 로더 윈도우가 열려있지 않습니다.");
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ShowCameraMenu()
|
|
{
|
|
var menu = new GenericMenu();
|
|
|
|
var cameras = FindObjectsByType<Camera>(FindObjectsSortMode.None);
|
|
foreach (var cam in cameras)
|
|
{
|
|
Camera capturedCam = cam;
|
|
menu.AddItem(new GUIContent(cam.name), _selectedCamera == cam, () =>
|
|
{
|
|
_selectedCamera = capturedCam;
|
|
});
|
|
}
|
|
|
|
if (cameras.Length == 0)
|
|
{
|
|
menu.AddDisabledItem(new GUIContent("카메라를 찾을 수 없습니다"));
|
|
}
|
|
|
|
menu.ShowAsContext();
|
|
}
|
|
|
|
private void CapturePreview()
|
|
{
|
|
if (_previewTexture != null)
|
|
{
|
|
DestroyImmediate(_previewTexture);
|
|
}
|
|
|
|
_previewTexture = CaptureImage();
|
|
}
|
|
|
|
private Texture2D CaptureImage()
|
|
{
|
|
Camera camera = GetCaptureCamera();
|
|
if (camera == null)
|
|
{
|
|
UnityEngine.Debug.LogError("캡처할 카메라를 찾을 수 없습니다.");
|
|
return null;
|
|
}
|
|
|
|
// RenderTexture 생성
|
|
RenderTexture rt = new RenderTexture(_width, _height, 24, RenderTextureFormat.ARGB32);
|
|
rt.antiAliasing = 8;
|
|
|
|
// 카메라 렌더링
|
|
RenderTexture prevRT = camera.targetTexture;
|
|
camera.targetTexture = rt;
|
|
camera.Render();
|
|
camera.targetTexture = prevRT;
|
|
|
|
// Texture2D로 변환
|
|
RenderTexture prevActive = RenderTexture.active;
|
|
RenderTexture.active = rt;
|
|
|
|
Texture2D texture = new Texture2D(_width, _height, TextureFormat.RGB24, false);
|
|
texture.ReadPixels(new Rect(0, 0, _width, _height), 0, 0);
|
|
texture.Apply();
|
|
|
|
RenderTexture.active = prevActive;
|
|
|
|
// 정리
|
|
DestroyImmediate(rt);
|
|
|
|
return texture;
|
|
}
|
|
|
|
private Camera GetCaptureCamera()
|
|
{
|
|
if (_useSceneCamera)
|
|
{
|
|
// Scene View 카메라 가져오기
|
|
var sceneView = SceneView.lastActiveSceneView;
|
|
if (sceneView != null)
|
|
{
|
|
return sceneView.camera;
|
|
}
|
|
}
|
|
|
|
return _selectedCamera;
|
|
}
|
|
|
|
private void CaptureAndSave()
|
|
{
|
|
Texture2D texture = CaptureImage();
|
|
if (texture == null) return;
|
|
|
|
// PNG로 인코딩
|
|
byte[] bytes = texture.EncodeToPNG();
|
|
DestroyImmediate(texture);
|
|
|
|
// 저장 경로 확인
|
|
string fullPath = Path.Combine(_savePath, _fileName + ".png");
|
|
|
|
// 디렉토리 확인
|
|
string directory = Path.GetDirectoryName(fullPath);
|
|
if (!Directory.Exists(directory))
|
|
{
|
|
Directory.CreateDirectory(directory);
|
|
}
|
|
|
|
// 파일 저장
|
|
File.WriteAllBytes(fullPath, bytes);
|
|
|
|
// 에셋 데이터베이스 갱신
|
|
AssetDatabase.Refresh();
|
|
|
|
// 텍스처 임포트 설정
|
|
string assetPath = fullPath.Replace("\\", "/");
|
|
TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
|
if (importer != null)
|
|
{
|
|
importer.textureType = TextureImporterType.Sprite;
|
|
importer.maxTextureSize = 1024;
|
|
importer.SaveAndReimport();
|
|
}
|
|
|
|
UnityEngine.Debug.Log($"썸네일 저장됨: {fullPath}");
|
|
|
|
// 프리뷰 업데이트
|
|
_previewTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
|
|
|
|
// 데이터베이스 갱신
|
|
if (_database != null)
|
|
{
|
|
if (_currentSceneInfo != null)
|
|
{
|
|
_currentSceneInfo.thumbnailPath = assetPath;
|
|
EditorUtility.SetDirty(_database);
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
else
|
|
{
|
|
// _currentSceneInfo가 없으면 데이터베이스 전체 갱신
|
|
RefreshSceneListDirectly();
|
|
}
|
|
}
|
|
|
|
// 배경 씬 로더 윈도우 갱신
|
|
var loaderWindow = GetWindow<BackgroundSceneLoaderWindow>(false, null, false);
|
|
if (loaderWindow != null)
|
|
{
|
|
// 씬 목록 갱신 (리플렉션)
|
|
var refreshMethod = typeof(BackgroundSceneLoaderWindow).GetMethod("RefreshSceneList",
|
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
|
if (refreshMethod != null)
|
|
{
|
|
refreshMethod.Invoke(loaderWindow, null);
|
|
}
|
|
|
|
// 썸네일 캐시 갱신
|
|
loaderWindow.RefreshThumbnail(assetPath);
|
|
}
|
|
|
|
EditorUtility.DisplayDialog("완료", $"썸네일이 저장되었습니다.\n{fullPath}", "확인");
|
|
}
|
|
|
|
private void CaptureAllBackgroundScenes()
|
|
{
|
|
if (_database == null)
|
|
{
|
|
EditorUtility.DisplayDialog("오류", "배경 씬 데이터베이스를 찾을 수 없습니다.", "확인");
|
|
return;
|
|
}
|
|
|
|
if (_database.scenes.Count == 0)
|
|
{
|
|
EditorUtility.DisplayDialog("오류", "배경 씬이 없습니다.", "확인");
|
|
return;
|
|
}
|
|
|
|
// 확인 다이얼로그
|
|
if (!EditorUtility.DisplayDialog("일괄 캡처",
|
|
$"총 {_database.scenes.Count}개의 배경 씬 썸네일을 캡처합니다.\n" +
|
|
"각 씬을 로드하고 카메라를 찾아 캡처합니다.\n\n" +
|
|
"진행하시겠습니까?",
|
|
"예", "아니오"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
int successCount = 0;
|
|
int failCount = 0;
|
|
|
|
try
|
|
{
|
|
for (int i = 0; i < _database.scenes.Count; i++)
|
|
{
|
|
var sceneInfo = _database.scenes[i];
|
|
|
|
EditorUtility.DisplayProgressBar("썸네일 캡처 중...",
|
|
$"{sceneInfo.sceneName} ({i + 1}/{_database.scenes.Count})",
|
|
(float)i / _database.scenes.Count);
|
|
|
|
// 이미 썸네일이 있으면 스킵
|
|
if (!string.IsNullOrEmpty(sceneInfo.thumbnailPath) &&
|
|
File.Exists(sceneInfo.thumbnailPath))
|
|
{
|
|
successCount++;
|
|
continue;
|
|
}
|
|
|
|
// 씬 로드
|
|
var scene = UnityEditor.SceneManagement.EditorSceneManager.OpenScene(
|
|
sceneInfo.scenePath,
|
|
UnityEditor.SceneManagement.OpenSceneMode.Additive);
|
|
|
|
// 카메라 찾기
|
|
Camera cam = null;
|
|
var rootObjects = scene.GetRootGameObjects();
|
|
foreach (var obj in rootObjects)
|
|
{
|
|
cam = obj.GetComponentInChildren<Camera>();
|
|
if (cam != null) break;
|
|
}
|
|
|
|
if (cam == null)
|
|
{
|
|
cam = Camera.main;
|
|
}
|
|
|
|
if (cam != null)
|
|
{
|
|
// 캡처
|
|
_selectedCamera = cam;
|
|
_useSceneCamera = false;
|
|
|
|
Texture2D texture = CaptureImage();
|
|
if (texture != null)
|
|
{
|
|
string savePath = Path.GetDirectoryName(sceneInfo.scenePath);
|
|
string fullPath = Path.Combine(savePath, sceneInfo.sceneName + ".png");
|
|
|
|
byte[] bytes = texture.EncodeToPNG();
|
|
File.WriteAllBytes(fullPath, bytes);
|
|
DestroyImmediate(texture);
|
|
|
|
sceneInfo.thumbnailPath = fullPath.Replace("\\", "/");
|
|
successCount++;
|
|
}
|
|
else
|
|
{
|
|
failCount++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UnityEngine.Debug.LogWarning($"카메라를 찾을 수 없음: {sceneInfo.sceneName}");
|
|
failCount++;
|
|
}
|
|
|
|
// 씬 언로드
|
|
UnityEditor.SceneManagement.EditorSceneManager.CloseScene(scene, true);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
EditorUtility.ClearProgressBar();
|
|
}
|
|
|
|
// 데이터베이스 저장
|
|
EditorUtility.SetDirty(_database);
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
|
|
EditorUtility.DisplayDialog("완료",
|
|
$"썸네일 캡처 완료\n성공: {successCount}개\n실패: {failCount}개",
|
|
"확인");
|
|
}
|
|
}
|
|
}
|