147 lines
5.0 KiB
C#
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;
|
|
}
|
|
}
|
|
} |