Skip to content

Instantly share code, notes, and snippets.

@Mylab6
Created May 5, 2022 17:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mylab6/ba9e473c486242ed600f7d1367f7a880 to your computer and use it in GitHub Desktop.
Save Mylab6/ba9e473c486242ed600f7d1367f7a880 to your computer and use it in GitHub Desktop.
Texture Cruncher for Unity. Dramatically reduce build sizes by reducing Max texture size, must be inside of an Editor folder.
using UnityEditor;
using UnityEngine;
using System.Collections;
using System.Linq;
public class TextureCruncher : EditorWindow
{
#region Variables
int compressionQuality = 100;
int processingSpeed = 10;
IEnumerator jobRoutine;
IEnumerator messageRoutine;
float progressCount = 0f;
float totalCount = 1f;
#endregion
#region Properties
float NormalizedProgress
{
get { return progressCount / totalCount; }
}
float Progress
{
get { return progressCount / totalCount * 100f; }
}
string FormattedProgress
{
get { return Progress.ToString("0.00") + "%"; }
}
#endregion
#region Script Lifecylce
[MenuItem("Window/Texture Cruncher")]
static void Init()
{
var window = (TextureCruncher)EditorWindow.GetWindow(typeof(TextureCruncher));
window.Show();
}
public void OnInspectorUpdate()
{
Repaint();
}
void OnGUI()
{
EditorGUILayout.LabelField("Texture Cruncher", EditorStyles.boldLabel);
compressionQuality = EditorGUILayout.IntSlider("Compression quality:", compressionQuality, 0, 100);
processingSpeed = EditorGUILayout.IntSlider("Processing speed:", processingSpeed, 1, 20);
maxTextureSize = EditorGUILayout.IntField("Max Texture Size", maxTextureSize);
string buttonLabel = jobRoutine != null ? "Cancel" : "Begin";
if (GUILayout.Button(buttonLabel))
{
if (jobRoutine != null)
{
messageRoutine = DisplayMessage("Cancelled. " + FormattedProgress + " complete!", 4f);
jobRoutine = null;
}
else
{
jobRoutine = CrunchTextures();
}
}
if (jobRoutine != null)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel(FormattedProgress);
var rect = EditorGUILayout.GetControlRect();
rect.width = rect.width * NormalizedProgress;
GUI.Box(rect, GUIContent.none);
EditorGUILayout.EndHorizontal();
}
else if (!string.IsNullOrEmpty(_message))
{
EditorGUILayout.HelpBox(_message, MessageType.None);
}
}
void OnEnable()
{
EditorApplication.update += HandleCallbackFunction;
}
void HandleCallbackFunction()
{
if (jobRoutine != null && !jobRoutine.MoveNext())
jobRoutine = null;
if (messageRoutine != null && !messageRoutine.MoveNext())
messageRoutine = null;
}
void OnDisable()
{
EditorApplication.update -= HandleCallbackFunction;
}
#endregion
#region Logic
string _message = null;
public int maxTextureSize = 1024;
IEnumerator DisplayMessage(string message, float duration = 0f)
{
if (duration <= 0f || string.IsNullOrEmpty(message))
goto Exit;
_message = message;
while (duration > 0)
{
duration -= 0.01667f;
yield return null;
}
Exit:
_message = string.Empty;
}
IEnumerator CrunchTextures()
{
DisplayMessage(string.Empty);
var assets = AssetDatabase.FindAssets("t:texture", null).Select(o => AssetImporter.GetAtPath(AssetDatabase.GUIDToAssetPath(o)) as TextureImporter);
var eligibleAssets = assets.Where(o => o != null).Where(o => o.compressionQuality != compressionQuality || !o.crunchedCompression || o.maxTextureSize != maxTextureSize);
totalCount = (float)eligibleAssets.Count();
progressCount = 0f;
int quality = compressionQuality;
int limiter = processingSpeed;
foreach (var textureImporter in eligibleAssets)
{
progressCount += 1f;
textureImporter.compressionQuality = quality;
textureImporter.crunchedCompression = true;
textureImporter.maxTextureSize = maxTextureSize;
AssetDatabase.ImportAsset(textureImporter.assetPath);
limiter -= 1;
if (limiter <= 0)
{
yield return null;
limiter = processingSpeed;
}
}
messageRoutine = DisplayMessage("Crunching complete!", 6f);
jobRoutine = null;
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment