Initial Commit

This commit is contained in:
jellejurre
2025-07-19 01:03:02 +02:00
commit e7904e3140
304 changed files with 22521 additions and 0 deletions

View File

@@ -0,0 +1,163 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace DreadScripts.TextureUtility
{
[System.Serializable]
public class ChannelTexture
{
public string name;
public Texture2D texture;
public bool invert;
public Color defaultColor;
public ColorMode mode = ColorMode.Red;
public enum ColorMode
{
Red,
Green,
Blue,
Alpha
}
public ChannelTexture(string n, int mode)
{
name = n;
SetMode(mode, true);
if (n == "Alpha")
defaultColor = Color.white;
}
public void SetMode(int i, bool ignoreSave = false)
{
switch (i)
{
case 0:
mode = ColorMode.Red;
break;
case 1:
mode = ColorMode.Green;
break;
case 2:
mode = ColorMode.Blue;
break;
case 3:
mode = ColorMode.Alpha;
break;
}
if (!ignoreSave)
{
EditorPrefs.SetInt("TextureUtilityChannel" + name, i);
}
}
public Texture2D GetChannelColors(int width, int height, out float[] colors, bool unloadTempTexture)
{
Texture2D textureToUse;
if (texture)
textureToUse = texture;
else
{
textureToUse = new Texture2D(1, 1, TextureFormat.RGBA32, false, true);
textureToUse.SetPixel(0, 0, defaultColor);
textureToUse.Apply();
}
Texture2D newTexture = TextureUtility.GetColors(textureToUse, width, height, out Color[] myColors, unloadTempTexture);
colors = myColors.Select(c =>
{
switch (mode)
{
case ColorMode.Red:
return c.r;
case ColorMode.Green:
return c.g;
case ColorMode.Blue:
return c.b;
default:
return c.a;
}
}).ToArray();
if (invert)
{
for (int i = 0; i < colors.Length; i++)
{
colors[i] = 1 - colors[i];
}
}
if (!texture && unloadTempTexture)
Object.DestroyImmediate(textureToUse);
return newTexture;
}
public void DrawGUI()
{
GUIStyle buttonGroupStyle = new GUIStyle(GUI.skin.GetStyle("toolbarbutton")) {padding = new RectOffset(1, 1, 1, 1), margin = new RectOffset(0, 0, 1, 1)};
using (new GUILayout.VerticalScope("box"))
{
using (new GUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
GUILayout.Label(name, "boldlabel");
GUILayout.FlexibleSpace();
}
using (new GUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
bool dummy;
EditorGUI.BeginChangeCheck();
dummy = GUILayout.Toggle(mode == ColorMode.Red, "R", buttonGroupStyle, GUILayout.Width(16));
if (EditorGUI.EndChangeCheck())
if (dummy)
SetMode(0);
EditorGUI.BeginChangeCheck();
dummy = GUILayout.Toggle(mode == ColorMode.Green, "G", buttonGroupStyle, GUILayout.Width(16));
if (EditorGUI.EndChangeCheck())
if (dummy)
SetMode(1);
EditorGUI.BeginChangeCheck();
dummy = GUILayout.Toggle(mode == ColorMode.Blue, "B", buttonGroupStyle, GUILayout.Width(16));
if (EditorGUI.EndChangeCheck())
if (dummy)
SetMode(2);
EditorGUI.BeginChangeCheck();
dummy = GUILayout.Toggle(mode == ColorMode.Alpha, "A", buttonGroupStyle, GUILayout.Width(16));
if (EditorGUI.EndChangeCheck())
if (dummy)
SetMode(3);
GUILayout.FlexibleSpace();
}
using (new GUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
Rect myTextureRect = GUILayoutUtility.GetRect(66, 66);
Rect myColorRect = new Rect(myTextureRect) {x = myTextureRect.x + 1, y = myTextureRect.y + 45, width = 20, height = 20};
if (!texture)
defaultColor = EditorGUI.ColorField(myColorRect, GUIContent.none, defaultColor, false, false, false);
texture = (Texture2D) EditorGUI.ObjectField(myTextureRect, texture, typeof(Texture2D), false);
if (!texture)
defaultColor = EditorGUI.ColorField(myColorRect, GUIContent.none, defaultColor, false, false, false);
GUILayout.FlexibleSpace();
}
invert = GUILayout.Toggle(invert, "Invert", "toolbarbutton");
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 50ad0f4ea47ebb449b51d9cf0321eee8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,373 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace DreadScripts.TextureUtility
{
public class TextureAutoPackerWindow : EditorWindow
{
private static TextureAutoPackerData data;
private static SerializedObject serializedObject;
private static SerializedProperty _active;
private static SerializedProperty _activeModules;
private static UnityEditorInternal.ReorderableList modulesList;
private static Texture2D titleTexture;
[MenuItem("DreadTools/Utility/Texture Auto-Packer")]
public static void ShowWindow()
{
EditorWindow w = GetWindow<TextureAutoPackerWindow>(false, "Texture Auto-Packer", true);
if (!titleTexture)
{
titleTexture = TextureUtility.GetColors((Texture2D)EditorGUIUtility.IconContent("Texture2D Icon").image, 16, 16, out _);
titleTexture.Apply();
}
w.titleContent.image = titleTexture;
}
private void OnEnable()
{
data = TextureAutoPackerData.GetInstance();
serializedObject = new SerializedObject(data);
_active = serializedObject.FindProperty("active");
_activeModules = serializedObject.FindProperty("activeModules");
modulesList = new UnityEditorInternal.ReorderableList(serializedObject, _activeModules, true, true, true, false)
{
drawElementCallback = DrawElement,
drawHeaderCallback = DrawHeader
};
}
private void DrawHeader(Rect rect)
{
EditorGUI.LabelField(rect, "Active Modules");
}
private void DrawElement(Rect rect, int index, bool isActive, bool isFocused)
{
if (!(index < _activeModules.arraySize && index >= 0))
return;
rect.y += 2;
rect.height = EditorGUIUtility.singleLineHeight;
if (GUI.Button(new Rect(rect.x, rect.y, 20, rect.height), "X"))
{
_activeModules.DeleteArrayElementAtIndex(index);
return;
}
rect.x += 20;
rect.width -= 20;
_activeModules.GetArrayElementAtIndex(index).objectReferenceValue = (TextureAutoPackerModule)EditorGUI.ObjectField(rect, _activeModules.GetArrayElementAtIndex(index).objectReferenceValue, typeof(TextureAutoPackerModule), false);
}
private void OnGUI()
{
serializedObject.Update();
Color og = GUI.backgroundColor;
GUI.backgroundColor = _active.boolValue ? Color.green : Color.grey;
_active.boolValue = GUILayout.Toggle(_active.boolValue, new GUIContent("Active","Determine whether the Auto-Packer should initiate on texture import"), "Toolbarbutton");
GUI.backgroundColor = og;
EditorGUI.BeginDisabledGroup(!_active.boolValue);
modulesList.DoLayoutList();
if (GUILayout.Button(new GUIContent("Force Check", "Initiate the Auto-Packer without having to trigger a texture import")))
{
TextureAutoPacker.InitiateAutoPacking();
TextureAutoPackerProcessor.OnAutoPackingEnd();
}
EditorGUI.EndDisabledGroup();
serializedObject.ApplyModifiedProperties();
}
}
[CustomEditor(typeof(TextureAutoPackerModule))]
public class TextureAutoPacker : Editor
{
static GUIContent removeIcon;
TextureAutoPackerModule module;
SerializedProperty packingList;
GUIStyle freeButtonStyle;
public override void OnInspectorGUI()
{
freeButtonStyle = new GUIStyle("toolbarbutton") { padding = new RectOffset(1, 1, 1, 1) };
serializedObject.Update();
if (GUILayout.Button(new GUIContent("Add","Create a new Auto-Packed texture"), "toolbarbutton"))
{
module.packedTextures.Add(new AutoPackedTexture());
serializedObject.Update();
}
for (int i = packingList.arraySize - 1; i >= 0; i--)
DrawPackingProperty(i);
serializedObject.ApplyModifiedProperties();
}
private void OnEnable()
{
module = (TextureAutoPackerModule)target;
packingList = serializedObject.FindProperty("packedTextures");
removeIcon = EditorGUIUtility.IconContent("winbtn_win_close");
}
static bool Running;
public static bool InitiateAutoPacking()
{
bool HasPacked=false;
if (Running)
return true;
Running = true;
TextureAutoPackerData data = TextureAutoPackerData.GetInstance();
if (!data.active)
return false;
data.activeModules.ForEach(m =>
{
if (!m)
goto Skip;
SerializedObject module = new SerializedObject(m);
module.Update();
for (int i = 0; i < m.packedTextures.Count; i++)
{
if (m.packedTextures[i].WasModified())
{
HasPacked = true;
string newTexturePath = m.packedTextures[i].Pack();
if (string.IsNullOrEmpty(newTexturePath))
goto Skip;
SerializedProperty packedTexture = module.FindProperty("packedTextures").GetArrayElementAtIndex(i);
SerializedProperty hashes = packedTexture.FindPropertyRelative("channelsHashes");
for (int j = 0; j < 4; j++)
{
hashes.GetArrayElementAtIndex(j).stringValue = string.Empty;
if (m.packedTextures[i].channels[j].texture)
hashes.GetArrayElementAtIndex(j).stringValue = m.packedTextures[i].channels[j].texture.imageContentsHash.ToString();
}
packedTexture.FindPropertyRelative("forceModified").boolValue = false;
AssetDatabase.ImportAsset(newTexturePath, ImportAssetOptions.ForceUpdate);
TextureAutoPackerProcessor.PathToProperty.Add(new System.Tuple<string, SerializedProperty>(newTexturePath, packedTexture.FindPropertyRelative("packed")));
}
}
module.ApplyModifiedPropertiesWithoutUndo();
Skip:;
});
Running = false;
return HasPacked;
}
public void DrawPackingProperty(int index)
{
SerializedProperty t = packingList.GetArrayElementAtIndex(index);
SerializedProperty _name = t.FindPropertyRelative("name");
SerializedProperty _expanded = t.FindPropertyRelative("expanded");
SerializedProperty _channels = t.FindPropertyRelative("channels");
SerializedProperty _packed = t.FindPropertyRelative("packed");
SerializedProperty _encoding = t.FindPropertyRelative("encoding");
SerializedProperty _quality = t.FindPropertyRelative("jpgQuality");
SerializedProperty _modified = t.FindPropertyRelative("forceModified");
AutoPackedTexture autoTexture = ((TextureAutoPackerModule)t.serializedObject.targetObject).packedTextures[index];
using (new GUILayout.VerticalScope("box"))
{
using (new GUILayout.HorizontalScope())
{
using (new GUILayout.HorizontalScope("toolbarbutton", GUILayout.Width(12)))
_expanded.boolValue = GUILayout.Toggle(_expanded.boolValue, GUIContent.none, "foldout", GUILayout.Width(10));
using (new GUILayout.HorizontalScope("toolbarbutton"))
_name.stringValue = EditorGUILayout.TextField(GUIContent.none, _name.stringValue, GUI.skin.label);
if (GUILayout.Button(removeIcon, freeButtonStyle, GUILayout.Width(17)))
{
packingList.DeleteArrayElementAtIndex(index);
return;
}
}
if (_expanded.boolValue)
{
using (new GUILayout.HorizontalScope("box"))
{
_encoding.enumValueIndex = (int)(TextureUtility.TexEncoding)EditorGUILayout.EnumPopup((TextureUtility.TexEncoding)_encoding.enumValueIndex, GUILayout.Width(95));
EditorGUI.BeginDisabledGroup(_encoding.enumValueIndex != 1);
EditorGUIUtility.labelWidth = 50;
_quality.intValue = EditorGUILayout.IntSlider("Quality", _quality.intValue, 1, 100);
EditorGUIUtility.labelWidth = 0;
EditorGUI.EndDisabledGroup();
}
using (new GUILayout.HorizontalScope())
{
for (int i = 0; i < _channels.arraySize; i++)
{
if (DrawChannelProperty(_channels.GetArrayElementAtIndex(i)))
_modified.boolValue = true;
}
GUILayout.Label("", GUI.skin.verticalSlider, GUILayout.Height(133));
using (new GUILayout.VerticalScope("box"))
{
using (new GUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
GUILayout.Label("Packed", "boldlabel");
GUILayout.FlexibleSpace();
}
GUILayout.Label(GUIContent.none);
using (new GUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
_packed.objectReferenceValue = (Texture2D)EditorGUILayout.ObjectField("", _packed.objectReferenceValue, typeof(Texture2D), false, GUILayout.Width(66));
GUILayout.FlexibleSpace();
}
using (new GUILayout.HorizontalScope())
{
if (GUILayout.Button("Force Pack", "toolbarbutton"))
{
string newTexturePath = autoTexture.Pack();
if (!string.IsNullOrEmpty(newTexturePath))
{
AssetDatabase.ImportAsset(newTexturePath);
_packed.objectReferenceValue = AssetDatabase.LoadAssetAtPath<Texture2D>(newTexturePath);
}
}
}
}
}
}
}
}
public bool DrawChannelProperty(SerializedProperty channel)
{
bool edited = false;
SerializedProperty _name = channel.FindPropertyRelative("name");
SerializedProperty _texture = channel.FindPropertyRelative("texture");
SerializedProperty _invert = channel.FindPropertyRelative("invert");
SerializedProperty _mode = channel.FindPropertyRelative("mode");
GUIStyle buttonGroupStyle = new GUIStyle(GUI.skin.GetStyle("toolbarbutton")) { padding = new RectOffset(1, 1, 1, 1), margin = new RectOffset(0, 0, 1, 1) };
using (new GUILayout.VerticalScope("box"))
{
using (new GUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
GUILayout.Label(_name.stringValue, "boldlabel");
GUILayout.FlexibleSpace();
}
using (new GUILayout.HorizontalScope())
{
EditorGUI.BeginChangeCheck();
GUILayout.FlexibleSpace();
bool dummy;
EditorGUI.BeginChangeCheck();
dummy = GUILayout.Toggle(_mode.enumValueIndex == (int)ChannelTexture.ColorMode.Red, "R", buttonGroupStyle, GUILayout.Width(16));
if (EditorGUI.EndChangeCheck())
if (dummy)
_mode.enumValueIndex = 0;
EditorGUI.BeginChangeCheck();
dummy = GUILayout.Toggle(_mode.enumValueIndex == (int)ChannelTexture.ColorMode.Green, "G", buttonGroupStyle, GUILayout.Width(16));
if (EditorGUI.EndChangeCheck())
if (dummy)
_mode.enumValueIndex = 1;
EditorGUI.BeginChangeCheck();
dummy = GUILayout.Toggle(_mode.enumValueIndex == (int)ChannelTexture.ColorMode.Blue, "B", buttonGroupStyle, GUILayout.Width(16));
if (EditorGUI.EndChangeCheck())
if (dummy)
_mode.enumValueIndex = 2;
EditorGUI.BeginChangeCheck();
dummy = GUILayout.Toggle(_mode.enumValueIndex == (int)ChannelTexture.ColorMode.Alpha, "A", buttonGroupStyle, GUILayout.Width(16));
if (EditorGUI.EndChangeCheck())
if (dummy)
_mode.enumValueIndex = 3;
GUILayout.FlexibleSpace();
if (EditorGUI.EndChangeCheck())
if (_texture.objectReferenceValue)
edited = true;
}
using (new GUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
_texture.objectReferenceValue = (Texture2D)EditorGUILayout.ObjectField("", _texture.objectReferenceValue, typeof(Texture2D), false, GUILayout.Width(66));
GUILayout.FlexibleSpace();
}
EditorGUI.BeginChangeCheck();
_invert.boolValue = GUILayout.Toggle(_invert.boolValue, "Invert", "toolbarbutton");
if (EditorGUI.EndChangeCheck())
if (_texture.objectReferenceValue)
edited = true;
}
return edited;
}
}
public class TextureAutoPackerProcessor : AssetPostprocessor
{
public static List<System.Tuple<string, SerializedProperty>> PathToProperty = new List<System.Tuple<string, SerializedProperty>>();
public static bool TextureImported = false;
void OnPostprocessTexture(Texture2D texture)
{
TextureImported = true;
}
public static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
if (TextureImported)
{
TextureImported = false;
if (!TextureAutoPacker.InitiateAutoPacking())
OnAutoPackingEnd();
}
}
public static void OnAutoPackingEnd()
{
PathToProperty.ForEach(t =>
{
t.Item2.serializedObject.Update();
t.Item2.objectReferenceValue = AssetDatabase.LoadAssetAtPath<Texture2D>(t.Item1);
t.Item2.serializedObject.ApplyModifiedPropertiesWithoutUndo();
});
PathToProperty.Clear();
}
}
public abstract class TAPDreadData<T> : ScriptableObject where T : ScriptableObject
{
private static T _instance = null;
private static string _SavePath;
protected static T GetInstance(string SavePath)
{
_SavePath = SavePath;
if (!_instance && Exists())
{
_instance = AssetDatabase.LoadAssetAtPath<T>(SavePath);
}
if (!_instance)
{
_instance = CreateInstance<T>();
string directoryPath = System.IO.Path.GetDirectoryName(SavePath);
if (!System.IO.Directory.Exists(directoryPath))
System.IO.Directory.CreateDirectory(directoryPath);
AssetDatabase.CreateAsset(_instance, _SavePath);
}
return _instance;
}
public static bool Exists()
{
return System.IO.File.Exists(_SavePath);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e8921d280a781e14bae3a414c99945a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace DreadScripts.TextureUtility
{
[System.Serializable]
public class TextureAutoPackerData : TAPDreadData<TextureAutoPackerData>
{
public bool active;
public List<TextureAutoPackerModule> activeModules = new List<TextureAutoPackerModule>();
private static readonly string SavePath = "Assets/DreadScripts/Saved Data/Texture Utility/TextureAutoPackerData.asset";
public static TextureAutoPackerData GetInstance()
{
return GetInstance(SavePath);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ca85679a83ff9c48b424bb5471ad605
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,69 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace DreadScripts.TextureUtility
{
[System.Serializable]
[CreateAssetMenu(fileName = "New Auto-Packer Module", menuName = "DreadScripts/Auto-Packer Module")]
public class TextureAutoPackerModule : ScriptableObject
{
public List<AutoPackedTexture> packedTextures;
public TextureAutoPackerModule()
{
packedTextures = new List<AutoPackedTexture>();
}
}
[System.Serializable]
public class AutoPackedTexture
{
public bool expanded;
public bool forward=true;
public string name;
public ChannelTexture[] channels;
public string[] channelsHashes;
public bool forceModified;
public Texture2D packed;
public TextureUtility.TexEncoding encoding;
public int jpgQuality = 75;
public AutoPackedTexture()
{
name = "New Packed Texture";
channels = new ChannelTexture[] {new ChannelTexture("Red",0), new ChannelTexture("Green", 1), new ChannelTexture("Blue", 2), new ChannelTexture("Alpha", 0) };
channelsHashes = new string[] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty };
encoding = TextureUtility.TexEncoding.SaveAsPNG;
}
public bool WasModified()
{
if (forceModified)
{
return true;
}
for (int i = 0; i < 4; i++)
{
string textureHash = string.Empty;
if (channels[i].texture)
textureHash = channels[i].texture.imageContentsHash.ToString();
if (textureHash != channelsHashes[i])
return true;
}
return false;
}
public string Pack()
{
string newTexturePath;
if (packed)
newTexturePath = TextureUtility.PackTexture(channels, AssetDatabase.GetAssetPath(packed), packed.width, packed.height, encoding, false, true, false);
else
newTexturePath = TextureUtility.PackTexture(channels, encoding, true, false);
return newTexturePath;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 57dd297cddefa864f9927f223270c5b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c470de7697213b34496ac48dd23b3be5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
{
"name": "com.dreadscripts.textureutility.Editor",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d5ab47812aae52a4a99db70b474a6420
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: