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("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(); 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; } } }