Created
June 2, 2015 01:58
-
-
Save hwei/a215ff1e7739c93d2ca7 to your computer and use it in GitHub Desktop.
Combine Texture Frames Tool for Unity 5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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