Created
July 27, 2015 19:04
-
-
Save anonymous/655731c176d3031689a5 to your computer and use it in GitHub Desktop.
KenneySpriteSheetBuilder.cs
This file contains 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 System.Collections.Generic; | |
using System.IO; | |
using System.Reflection; | |
using System.Xml; | |
using UnityEditor; | |
using UnityEngine; | |
class KenneySpriteSheetBuilder : AssetPostprocessor | |
{ | |
#region Customization | |
// | |
// If you want to only process kenney spritesheets in a specific folder you can do it by setting | |
// this string to the name of the folder relative to your assets directory. | |
// | |
const string m_RequiredRootFolder = null; | |
#endregion | |
#region Internals | |
// This is a brilliant method by unity form member numberkruncher | |
// Here's the post that provided the guts of this method, not taken quite verbatum: | |
// http://forum.unity3d.com/threads/getting-original-size-of-texture-asset-in-pixels.165295/ | |
public static bool GetImageSize(TextureImporter importer, out int width, out int height) | |
{ | |
if (importer != null) | |
{ | |
object[] args = new object[2] { 0, 0 }; | |
MethodInfo mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance); | |
mi.Invoke(importer, args); | |
width = (int)args[0]; | |
height = (int)args[1]; | |
return true; | |
} | |
height = width = 0; | |
return false; | |
} | |
private static void HandleSpritesheet(TextureImporter importer, XmlDocument document, ref int totalSprites) | |
{ | |
// don't over-write sprite sheets that have already been setup (either by hand, or previously). | |
if (importer.spriteImportMode != SpriteImportMode.Multiple) | |
{ | |
Vector2 pivot = new Vector2(0.5f, 0.5f); | |
importer.spriteImportMode = SpriteImportMode.Multiple; | |
List<SpriteMetaData> sprites = new List<SpriteMetaData>(); | |
int textureWidth = 0, | |
textureHeight = 0; | |
if (!GetImageSize(importer, out textureWidth, out textureHeight)) | |
{ | |
Debug.LogWarning("Couldn't determine the texture dimensions for this asset. Asset path is\"" + importer.assetPath + "\""); | |
} | |
foreach (XmlNode xmlNode in document.DocumentElement.ChildNodes) | |
{ | |
string childName = xmlNode.Name; | |
if (childName == "SubTexture") | |
{ | |
string | |
name = null, | |
x = null, | |
y = null, | |
width = null, | |
height = null; | |
int _x = 0, | |
_y = 0, | |
_width = 0, | |
_height = 0; | |
foreach (XmlAttribute attr in xmlNode.Attributes) | |
{ | |
switch (attr.Name) | |
{ | |
case "name": | |
name = attr.Value; | |
break; | |
case "x": | |
x = attr.Value; | |
break; | |
case "y": | |
y = attr.Value; | |
break; | |
case "width": | |
width = attr.Value; | |
break; | |
case "height": | |
height = attr.Value; | |
break; | |
// It seems like we can ignore these attributes coming from the shoebox exporter. | |
// If they need to be considered in the future we can add support here. | |
case "frameX": | |
case "frameY": | |
case "frameWidth": | |
case "frameHeight": | |
break; | |
default: | |
Debug.LogWarning("[Kenney] While loading a spritesheet, we found a subtexture attr that was unexpected... It was \"" + attr.Name + "\""); | |
break; | |
} | |
} | |
if (name == null) | |
{ | |
Debug.LogWarning("[Kenney] While loading a spritesheet, we found a subtexture without a name."); | |
continue; | |
} | |
if (x == null || !int.TryParse(x, out _x)) | |
{ | |
Debug.LogWarning("[Kenney] While loading a spritesheet, we found a subtexture without an x position. The name was \"" + name + "\""); | |
continue; | |
} | |
if (y == null || !int.TryParse(y, out _y)) | |
{ | |
Debug.LogWarning("[Kenney] While loading a spritesheet, we found a subtexture without a y position. The name was \"" + name + "\""); | |
continue; | |
} | |
if (width == null || !int.TryParse(width, out _width)) | |
{ | |
Debug.LogWarning("[Kenney] While loading a spritesheet, we found a subtexture without a width. The name was \"" + name + "\""); | |
continue; | |
} | |
if (height == null || !int.TryParse(height, out _height)) | |
{ | |
Debug.LogWarning("[Kenney] While loading a spritesheet, we found a subtexture without a height. The name was \"" + name + "\""); | |
continue; | |
} | |
SpriteMetaData meta = new SpriteMetaData(); | |
meta.name = name; | |
meta.pivot = pivot; | |
// note the required modification to the y position to work with unity sprite co-ords | |
meta.rect = new Rect(_x, textureHeight - _y - _height, _width, _height); | |
sprites.Add(meta); | |
} | |
} | |
if (sprites.Count > 0) | |
{ | |
totalSprites += sprites.Count; | |
importer.spritesheet = sprites.ToArray(); | |
// refresh the sprite sheet so it can apply our changes. | |
AssetDatabase.ImportAsset(importer.assetPath); | |
} | |
} | |
} | |
private static void HandleAsset(string asset, ref int totalSprites) | |
{ | |
if (m_RequiredRootFolder != null && !asset.Contains("Assets/" + m_RequiredRootFolder)) | |
{ | |
return; | |
} | |
AssetImporter importer = AssetImporter.GetAtPath(asset); | |
if (importer != null) | |
{ | |
if(!(importer is TextureImporter)) | |
{ | |
return; | |
} | |
if (((TextureImporter)importer).textureType == TextureImporterType.Sprite) | |
{ | |
string imagePath = asset; | |
string xmlPath = imagePath.Substring(0, imagePath.LastIndexOf('.')) + ".xml"; | |
if (File.Exists(xmlPath)) | |
{ | |
//document | |
XmlDocument document = new XmlDocument(); | |
document.Load(xmlPath); | |
//TODO: validate document. | |
HandleSpritesheet((TextureImporter)importer, document, ref totalSprites); | |
} | |
} | |
} | |
} | |
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPath) | |
{ | |
int totalSprites = 0; | |
foreach (var asset in importedAssets) | |
{ | |
HandleAsset(asset, ref totalSprites); | |
} | |
foreach (var asset in movedAssets) | |
{ | |
HandleAsset(asset, ref totalSprites); | |
} | |
foreach (var asset in movedFromAssetPath) | |
{ | |
HandleAsset(asset, ref totalSprites); | |
} | |
if (totalSprites > 0) | |
{ | |
Debug.Log("[Kenney] Successfully added " + totalSprites + " sprites!"); | |
} | |
} | |
#endregion | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment