Skip to content

Instantly share code, notes, and snippets.

@hwei
Created June 2, 2015 01:58
Show Gist options
  • Save hwei/a215ff1e7739c93d2ca7 to your computer and use it in GitHub Desktop.
Save hwei/a215ff1e7739c93d2ca7 to your computer and use it in GitHub Desktop.
Combine Texture Frames Tool for Unity 5
using UnityEngine;
using UnityEditor;
using System.Linq;
public class CombineTextureFrames : ScriptableWizard {
public Texture2D[] textures;
public Vector2 frameSize;
public Vector2 layout;
[MenuItem("Assets/Combine Texture Frames")]
static void CreateWizard () {
var wizard = ScriptableWizard.DisplayWizard<CombineTextureFrames> ("Combine Texture Frames", "Save");
var textures = Selection.objects.Where (o => o is Texture2D)
.OrderBy (o => o.name, new FileNameComparer())
.Cast<Texture2D> ().ToArray ();
wizard.textures = textures;
if (textures.Length == 0) {
wizard.frameSize = Vector2.zero;
wizard.layout = Vector2.zero;
}
else {
int width = int.MaxValue;
int height = int.MaxValue;
foreach (var t in textures) {
width = Mathf.Min (width, t.width);
height = Mathf.Min (height, t.height);
}
wizard.frameSize = new Vector2 (width, height);
int fullArea = width * height * textures.Length;
float squareSize = Mathf.Sqrt ((float) fullArea);
int layoutX = (int) Mathf.Ceil (squareSize / (float) width);
int layoutY = (textures.Length - 1) / layoutX + 1;
wizard.layout = new Vector2 (layoutX, layoutY);
}
}
void OnWizardCreate () {
var width = (int) (this.frameSize.x * this.layout.x);
var height = (int) (this.frameSize.y * this.layout.y);
var texResult = new Texture2D (width, height, TextureFormat.Alpha8, true);
int frameWidth = (int) this.frameSize.x;
int frameHeight = (int) this.frameSize.y;
int layoutWidth = (int) this.layout.x;
int layoutHeight = (int) this.layout.y;
int layoutX = 0;
int layoutY = 0;
foreach (var tex in this.textures) {
texResult.SetPixels(
layoutX * frameWidth, layoutY * frameHeight, frameWidth, frameHeight,
tex.GetPixels (0, 0, frameWidth, frameHeight));
if (++layoutX >= layoutWidth) {
++layoutY;
layoutX = 0;
}
}
texResult.Apply ();
var savePath = EditorUtility.SaveFilePanelInProject (
"Save the result", "texture", "png", "Save the result");
if (savePath != null) {
var bytes = texResult.EncodeToPNG ();
System.IO.File.WriteAllBytes (savePath, bytes);
AssetDatabase.ImportAsset (savePath);
}
}
class FileNameComparer : System.Collections.Generic.IComparer<string> {
#region IComparer implementation
public int Compare (string x, string y)
{
Debug.LogFormat ("Compare {0} {1}", x, y);
int posX = 0;
int posY = 0;
while (true) {
if (posX == x.Length) {
return posY == y.Length ? 0 : -1;
}
if (posY == y.Length) {
return 1;
}
char cx, cy;
int nx, ny;
posX = eatString(x, posX, out cx, out nx);
posY = eatString(y, posY, out cy, out ny);
var charResult = System.Collections.Generic.Comparer<char>.Default.Compare (cx, cy);
if (charResult != 0) {
return charResult;
}
var intResult = System.Collections.Generic.Comparer<int>.Default.Compare (nx, ny);
if (intResult != 0) {
return intResult;
}
}
}
#endregion
private static int eatString (string s, int pos, out char c, out int n) {
c = s[pos];
n = 0;
if (c < '0' || c > '9') {
return pos + 1;
}
while (true) {
n = n * 10 + (c - '0');
++pos;
if (pos == s.Length)
break;
c = s[pos];
if (c < '0' || c > '9')
break;
}
c = '0';
return pos;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment