안녕하세요. 인텔리원스튜디오(IntelliOneStudio)입니다.
이번 시간에는 Unity 에디터에서 프리팹을 렌더링하고, 그 결과를 RenderTexture에 저장한 후, 이를 Texture2D로 변환하여 에디터 창에 표시하고 파일로 저장하는 방법을 알아볼께요.
이 과정은 몇 가지 단계로 구성되며, 각각의 단계에서 필요한 코드 예제와 설명을 할거예요.
[참고] Unity에 대한 경험이 없었지만 챗GPT를 활용해서 3주만에 개발했어요. 약간의 수정은 있었지만 99% 코딩은 챗GTP가 했어요. 개발에 참고하세요.
* APP Store 에서 다운로드
https://apps.apple.com/kr/app/%EB%86%8D%EB%B6%80%EC%9D%98-%EA%BF%88/id6479183930
*Google Play 에서 다운로드
https://play.google.com/store/apps/details?id=com.intellione.farmersfirstdream&pcampaignid=web_share
아래와 같이 ChatGPT에게 질문했어요.
※ ChatGPT 답변 내용 중 제가 별도로 표시한 파란색 내용을 기준으로 읽으시면 좀 더 이해가 쉽게 될거예요.
[질문] 안녕 ChatGPT, 프리팹을 가지고 렌더 텍스처를 에디터에서 만드는 방법을 알려줄 수 있어? 구체적인 예제 코드와 설명도 부탁해.
[답변]
안녕하세요! 프리팹을 가지고 렌더 텍스처를 에디터에서 만드는 방법을 단계별로 설명해드리겠습니다. 이 과정을 통해 프리팹을 렌더링하고, 그 결과를 RenderTexture에 저장하여 Texture2D로 변환한 후, 이를 파일로 저장하는 방법을 배울 수 있습니다.
단계별 안내
- 렌더링 카메라 설정
- RenderTexture 생성 및 설정
- 프리팹 렌더링 및 RenderTexture 캡처
- 결과를 Texture2D로 변환하여 저장
1. 렌더링 카메라 설정
렌더링 카메라를 설정하기 위해 OnEnable 메서드에서 카메라와 RenderTexture를 초기화합니다. 카메라는 투명한 배경을 가지며, 정사영(orthographic) 모드로 설정됩니다.
2. RenderTexture 생성 및 설정
RenderTexture를 생성하고, 이를 카메라의 targetTexture로 설정합니다. RenderTexture는 알파 채널을 포함한 ARGB32 형식으로 설정하여 배경을 투명하게 유지합니다.
3. 프리팹 렌더링 및 RenderTexture 캡처
선택한 프리팹을 인스턴스화하고, 이를 렌더링하여 RenderTexture에 캡처합니다. 이후, RenderTexture의 내용을 Texture2D로 변환합니다.
4. 결과를 Texture2D로 변환하여 저장
변환된 Texture2D를 PNG 파일로 저장합니다. 사용자는 에디터 창에서 텍스처를 확인하고 저장할 수 있습니다.
코드 예제
아래는 Unity 에디터에서 프리팹을 렌더링하고, 그 결과를 RenderTexture로 저장한 후 Texture2D로 변환하는 스크립트 예제입니다.
에디터 스크립트 생성
먼저, Editor 폴더를 만들고 그 안에 에디터 스크립트를 생성합니다.
using UnityEditor;
using UnityEngine;
public class RenderPrefabToTextureEditor : EditorWindow
{
private GameObject prefab;
private Camera renderCamera;
private RenderTexture renderTexture;
private Texture2D resultTexture;
[MenuItem("Tools/Render Prefab to Texture")]
public static void ShowWindow()
{
GetWindow<RenderPrefabToTextureEditor>("Render Prefab to Texture");
}
private void OnEnable()
{
renderTexture = new RenderTexture(256, 256, 24, RenderTextureFormat.ARGB32);
renderTexture.useMipMap = false;
renderTexture.autoGenerateMips = false;
renderCamera = new GameObject("Render Camera").AddComponent<Camera>();
renderCamera.backgroundColor = Color.clear;
renderCamera.clearFlags = CameraClearFlags.SolidColor;
renderCamera.targetTexture = renderTexture;
renderCamera.orthographic = true; // 정사영 카메라로 설정
}
private void OnDisable()
{
if (renderCamera != null)
{
DestroyImmediate(renderCamera.gameObject);
}
if (renderTexture != null)
{
renderTexture.Release();
DestroyImmediate(renderTexture);
}
}
private void OnGUI()
{
GUILayout.Label("Select Prefab to Render", EditorStyles.boldLabel);
prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", prefab, typeof(GameObject), false);
if (GUILayout.Button("Render Prefab"))
{
RenderPrefab();
}
if (resultTexture != null)
{
GUILayout.Label("Rendered Texture", EditorStyles.boldLabel);
GUILayout.Label(resultTexture, GUILayout.Width(256), GUILayout.Height(256));
if (GUILayout.Button("Save Texture"))
{
SaveTexture();
}
}
}
private void RenderPrefab()
{
if (prefab == null)
{
Debug.LogError("Please select a prefab to render.");
return;
}
// 프리팹 인스턴스화
GameObject tempPrefabInstance = Instantiate(prefab, Vector3.zero, Quaternion.identity);
Bounds bounds = CalculateBounds(tempPrefabInstance);
renderCamera.orthographicSize = bounds.size.y / 2;
renderCamera.transform.position = bounds.center - new Vector3(0, 0, 10);
// 렌더링 수행
renderCamera.Render();
// RenderTexture를 Texture2D로 변환
resultTexture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false);
RenderTexture.active = renderTexture;
resultTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
resultTexture.Apply();
// 임시 오브젝트 삭제
RenderTexture.active = null;
DestroyImmediate(tempPrefabInstance);
}
private Bounds CalculateBounds(GameObject obj)
{
var renderers = obj.GetComponentsInChildren<Renderer>();
Bounds bounds = new Bounds(renderers[0].bounds.center, renderers[0].bounds.size);
foreach (var renderer in renderers)
{
bounds.Encapsulate(renderer.bounds);
}
return bounds;
}
private void SaveTexture()
{
if (resultTexture == null)
{
Debug.LogError("No texture to save.");
return;
}
byte[] bytes = resultTexture.EncodeToPNG();
string path = EditorUtility.SaveFilePanel("Save Texture", "", prefab.name + ".png", "png");
if (!string.IsNullOrEmpty(path))
{
System.IO.File.WriteAllBytes(path, bytes);
AssetDatabase.Refresh();
Debug.Log("Texture saved to " + path);
}
}
}
Unity 에디터에서 실행
- Unity 에디터를 열고 상단 메뉴에서 Tools > Render Prefab to Texture를 클릭하여 새로 생성한 에디터 창을 엽니다.
- 에디터 창이 열리면, Prefab 필드에 렌더링할 프리팹을 드래그 앤 드롭하거나 필드 우측의 작은 원 아이콘을 클릭하여 프리팹을 선택합니다.
- Render Prefab 버튼을 클릭하여 선택한 프리팹을 렌더링합니다. 이 과정에서 프리팹의 렌더링 결과가 에디터 창에 표시됩니다.
- 렌더링된 텍스처가 에디터 창에 표시된 것을 확인한 후, Save Texture 버튼을 클릭하여 결과 텍스처를 PNG 파일로 저장할 수 있습니다.
스크립트 설명
ShowWindow 메서드: Unity 에디터의 메뉴에 새 항목을 추가하고, 이를 클릭하면 에디터 창을 엽니다.
OnEnable 메서드: 에디터 창이 열릴 때 호출되며, RenderTexture와 렌더링 카메라를 초기화합니다.
OnDisable 메서드: 에디터 창이 닫힐 때 호출되며, 사용된 리소스를 해제합니다.
OnGUI 메서드: 에디터 창의 UI를 구성합니다. 프리팹을 선택하고 렌더링 및 저장 버튼을 제공합니다.
RenderPrefab 메서드: 선택한 프리팹을 인스턴스화하고, 이를 RenderTexture로 렌더링하여 Texture2D로 변환합니다. SaveTexture 메서드: 렌더링된 Texture2D를 PNG 파일로 저장합니다.
이 스크립트를 사용하면 Unity 에디터 내에서 프리팹을 선택하고, 이를 렌더링하여 결과를 텍스처로 저장할 수 있습니다.
이제 답변한 내용을 가지고 결과를 만들어볼께요.
결과는 이렇게 나와요.
오늘은 Unity 에디터에서 프리팹을 렌더링하고, 그 결과를 RenderTexture에 저장한 후, 이를 Texture2D로 변환하여 에디터 창에 표시하고 파일로 저장하는 방법을 알아봤어요.
오늘도 활기찬 하루되세요.
지금까지, 언제나 성장하는 인텔리원스튜디오(IntelliOneStudio)입니다.
감사합니다.