SummerGame/Assets/_Project/Scripts/Editor/IconGenerator.cs

147 lines
5.0 KiB
C#

using UnityEngine;
using UnityEditor;
using System.IO;
public class IconGenerator : EditorWindow
{
public Camera renderCamera;
public GameObject[] prefabs;
public string savePath = "Assets/_Project/Art/Icons/MetaPart/Bedroom";
public int imageSize = 2000;
public float padding = 1.2f;
public float minRadius = 0.3f;
public Vector3 cameraAngle = new Vector3(30f, 135f, 0f);
private Vector2 scrollPos;
[MenuItem("Tools/Icon Generator")]
public static void ShowWindow()
{
GetWindow<IconGenerator>("Icon Generator").minSize = new Vector2(300, 550);
}
void OnGUI()
{
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
GUILayout.Label("Settings", EditorStyles.boldLabel);
renderCamera = (Camera)EditorGUILayout.ObjectField("Render Camera", renderCamera, typeof(Camera), true);
savePath = EditorGUILayout.TextField("Save Path", savePath);
imageSize = EditorGUILayout.IntField("Image Size", imageSize);
padding = EditorGUILayout.Slider("Padding (Space around)", padding, 1f, 3f);
minRadius = EditorGUILayout.Slider("Min Radius", minRadius, 0.1f, 5f);
GUILayout.Space(5);
cameraAngle = EditorGUILayout.Vector3Field("Camera Angle", cameraAngle);
GUILayout.Space(10);
ScriptableObject target = this;
SerializedObject so = new SerializedObject(target);
SerializedProperty prefabsProperty = so.FindProperty("prefabs");
EditorGUILayout.PropertyField(prefabsProperty, true);
so.ApplyModifiedProperties();
EditorGUILayout.EndScrollView();
GUILayout.Space(5);
if (GUILayout.Button("Generate Icons", GUILayout.Height(40)))
{
if (renderCamera == null || prefabs == null || prefabs.Length == 0)
{
Debug.LogWarning("Please assign a camera and at least one prefab!");
return;
}
Generate();
}
GUILayout.Space(5);
}
void Generate()
{
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
Vector3 originalCamPos = renderCamera.transform.position;
Quaternion originalCamRot = renderCamera.transform.rotation; // Запоминаем оригинальный поворот
float originalOrthoSize = renderCamera.orthographicSize;
RenderTexture rt = new RenderTexture(imageSize, imageSize, 24);
renderCamera.targetTexture = rt;
Texture2D screenShot = new Texture2D(imageSize, imageSize, TextureFormat.ARGB32, false);
foreach (var prefab in prefabs)
{
if (prefab == null) continue;
GameObject instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
instance.transform.position = Vector3.zero;
Bounds bounds = CalculateBounds(instance);
Vector3 offset = new Vector3(-bounds.center.x, -bounds.min.y, -bounds.center.z);
instance.transform.position += offset;
bounds = CalculateBounds(instance);
renderCamera.transform.rotation = Quaternion.Euler(cameraAngle);
FrameCamera(renderCamera, bounds);
renderCamera.Render();
RenderTexture.active = rt;
screenShot.ReadPixels(new Rect(0, 0, imageSize, imageSize), 0, 0);
screenShot.Apply();
string fullPath = Path.Combine(savePath, prefab.name + ".png");
byte[] bytes = screenShot.EncodeToPNG();
File.WriteAllBytes(fullPath, bytes);
DestroyImmediate(instance);
}
renderCamera.transform.position = originalCamPos;
renderCamera.transform.rotation = originalCamRot;
renderCamera.orthographicSize = originalOrthoSize;
renderCamera.targetTexture = null;
RenderTexture.active = null;
DestroyImmediate(rt);
AssetDatabase.Refresh();
Debug.Log($"Successfully generated {prefabs.Length} icons in {savePath}");
}
Bounds CalculateBounds(GameObject obj)
{
Renderer[] renderers = obj.GetComponentsInChildren<Renderer>();
if (renderers.Length == 0) return new Bounds(obj.transform.position, Vector3.zero);
Bounds bounds = renderers[0].bounds;
foreach (Renderer r in renderers)
{
bounds.Encapsulate(r.bounds);
}
return bounds;
}
void FrameCamera(Camera cam, Bounds bounds)
{
float radius = Mathf.Max(bounds.extents.magnitude, minRadius) * padding;
if (cam.orthographic)
{
cam.orthographicSize = radius;
cam.transform.position = bounds.center - cam.transform.forward * 10f;
}
else
{
float fov = cam.fieldOfView * 0.5f * Mathf.Deg2Rad;
float distance = radius / Mathf.Sin(fov);
cam.transform.position = bounds.center - cam.transform.forward * distance;
}
}
}