SharedVRCStuff/TextureAtlasGenerator/TextureAtlasGenerator.cs

123 lines
4.6 KiB
C#

using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.IO;
namespace gay.lilyy.TextureAtlasGenerator
{
[CreateAssetMenu(fileName = "TextureAtlasSettings", menuName = "Texture Atlas/Settings")]
public class TextureAtlasSettings : ScriptableObject
{
public Texture2D[] textures;
public int atlasSize = 1024;
public int columns = 4;
public int rows = 4;
public string savePath = "Assets/Atlas.png";
}
[CustomEditor(typeof(TextureAtlasSettings))]
public class TextureAtlasEditor : Editor
{
private SerializedProperty texturesProp;
private SerializedProperty columnsProp;
private SerializedProperty rowsProp;
private void OnEnable()
{
texturesProp = serializedObject.FindProperty("textures");
columnsProp = serializedObject.FindProperty("columns");
rowsProp = serializedObject.FindProperty("rows");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.LabelField("Texture Atlas Settings", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(serializedObject.FindProperty("atlasSize"));
EditorGUILayout.PropertyField(columnsProp);
EditorGUILayout.PropertyField(rowsProp);
EditorGUILayout.PropertyField(serializedObject.FindProperty("savePath"));
DrawTextureGrid();
if (GUILayout.Button("Generate Atlas"))
{
GenerateAtlas();
}
serializedObject.ApplyModifiedProperties();
}
private void DrawTextureGrid()
{
int totalSlots = columnsProp.intValue * rowsProp.intValue;
if (texturesProp.arraySize != totalSlots)
texturesProp.arraySize = totalSlots;
EditorGUILayout.LabelField("Textures Grid", EditorStyles.boldLabel);
int gridWidth = 80;
int gridHeight = 80;
for (int y = 0; y < rowsProp.intValue; y++)
{
EditorGUILayout.BeginHorizontal();
for (int x = 0; x < columnsProp.intValue; x++)
{
int index = y * columnsProp.intValue + x;
SerializedProperty textureProp = texturesProp.GetArrayElementAtIndex(index);
textureProp.objectReferenceValue = (Texture2D)EditorGUILayout.ObjectField(
textureProp.objectReferenceValue, typeof(Texture2D), false,
GUILayout.Width(gridWidth), GUILayout.Height(gridHeight));
}
EditorGUILayout.EndHorizontal();
}
}
private void GenerateAtlas()
{
TextureAtlasSettings settings = (TextureAtlasSettings)target;
if (settings.textures == null || settings.textures.Length == 0)
{
Debug.LogError("No textures assigned!");
return;
}
Texture2D atlas = new Texture2D(settings.atlasSize, settings.atlasSize);
Color[] blackPixels = new Color[settings.atlasSize * settings.atlasSize];
for (int i = 0; i < blackPixels.Length; i++) blackPixels[i] = Color.black;
atlas.SetPixels(blackPixels);
int cellWidth = settings.atlasSize / settings.columns;
int cellHeight = settings.atlasSize / settings.rows;
for (int i = 0; i < settings.textures.Length; i++)
{
if (settings.textures[i] == null) continue;
int x = (i % settings.columns) * cellWidth;
int y = (settings.rows - 1 - (i / settings.columns)) * cellHeight;
Texture2D resized = ResizeTexture(settings.textures[i], cellWidth, cellHeight);
atlas.SetPixels(x, y, cellWidth, cellHeight, resized.GetPixels(), 0);
}
atlas.Apply();
byte[] bytes = atlas.EncodeToPNG();
File.WriteAllBytes(settings.savePath, bytes);
AssetDatabase.Refresh();
Debug.Log("Atlas saved at: " + settings.savePath);
}
private Texture2D ResizeTexture(Texture2D texture, int width, int height)
{
RenderTexture rt = new RenderTexture(width, height, 32);
Graphics.Blit(texture, rt);
Texture2D result = new Texture2D(width, height);
RenderTexture.active = rt;
result.ReadPixels(new Rect(0, 0, width, height), 0, 0);
result.Apply();
RenderTexture.active = null;
return result;
}
}
}