Etana
Topic Author
Posts: 17
Joined: 21 Aug 2016, 13:14

Shoebox converter and unity importer

14 Sep 2016, 11:47

Hi,
I've always used Shoebox when I needed to make sprite atlases ( http://renderhjs.net/shoebox/ )
It's nice application but it's default xml data is not obviously compatible with xaml so I made a simple .cmd converter , just copy paste this to .cmd, place it where you have your shoebox XMLs and just run it.
Program will search for all .xml files in current directory and convert those to new .xaml resourceDirectory files which you can just add as a resource to your xaml.
@ECHO OFF
@ECHO OFF
setlocal enabledelayedexpansion
set /a counter=0
                                                                         
for /f "delims=" %%a in ('dir /b *.xml') do (

  set currentXaml=%%a
  set strippedName=!currentXaml:~0,-4!
                                              
  echo ^<ResourceDictionary > !strippedName!.xaml
  echo xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" >> !strippedName!.xaml
  echo  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"^> >> !strippedName!.xaml     
  
  for /f delims^=^"^ tokens^=2 %%i  in ('type !currentXaml!') do (
  if !counter! GEQ 1 (
  REM.
  ) ELSE (
  set /a counter+=1
  
  set imagePath=%%i
  )                                                                          
  )
  
  set /a counter=0
  for /f tokens^=2^,4^,6^,8^,10^ delims^=^" %%a in ('type !currentXaml! ') do (
  if !counter! GEQ 1 (
  set key=%%a
  echo ^<ImageBrush x:Key="!key:~0,-4!" ImageSource="!imagePath!" Viewbox="%%b,%%c,%%d,%%e" ViewboxUnits="Absolute" Stretch="Fill"/^> >> !strippedName!.xaml
  ) ELSE (
  set /a counter+=1
  )
  )
  echo ^</ResourceDictionary^> >> !strippedName!.xaml
  )

Also I modified this unity importer to work with these converted xaml files
using UnityEditor;
using UnityEngine;
using System.Xml;
using System.Collections.Generic;

public class ShoeBoxReading : EditorWindow
{
    private Object text;
    private Texture2D texture2d;
    private SpriteAlignment pivot = SpriteAlignment.Center;
    private Vector2 customPivot = new Vector2(0.5f, 0.5f);

    [MenuItem("Tools/ShoeBoxReading/ShoeBox Import")]
    public static void Init()
    {
        EditorWindow.GetWindow(typeof(ShoeBoxReading), false, "ShoeBox Imported");
    }

    void OnGUI()
    {
        text = EditorGUILayout.ObjectField("File: ", text, typeof(TextAsset), false);
        texture2d = (Texture2D)EditorGUILayout.ObjectField("Texture: ", texture2d, typeof(Texture2D), false);
        pivot = (SpriteAlignment)EditorGUILayout.EnumPopup("Pivot: ", pivot);
        if (pivot == SpriteAlignment.Custom)
        {
            Vector2 customPivotTemp = EditorGUILayout.Vector2Field("Custom pivot:", customPivot);
            //user change value,, it can be more than 1 or less than 0
            if (customPivotTemp != customPivot)
            {
                if (customPivotTemp.x > 1)
                {
                    customPivotTemp.x = 1;
                }
                else if (customPivotTemp.x < 0)
                {
                    customPivotTemp.x = 0;
                }
                if (customPivotTemp.y > 1)
                {
                    customPivotTemp.y = 1;
                }
                else if (customPivotTemp.y < 0)
                {
                    customPivotTemp.y = 0;
                }
                //apply changes
                customPivot = customPivotTemp;
            }
        }

        if (GUILayout.Button("Read") && text != null && texture2d != null)
        {
            Read();
        }
    }

    void Read()
    {
        XmlTextReader reader = new XmlTextReader(AssetDatabase.GetAssetPath(text));
        Rect rect;
        List<SpriteMetaData> listSprite = new List<SpriteMetaData>();
        SpriteMetaData spritedata;
        int imageHeight = texture2d.height;
        
        int SpriteX;
        int SpriteY;
        int SpriteWidth;
        int SpriteHeight;

        Debug.Log("do I work?");
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                //if (reader.Name == "SubTexture")
                Debug.Log(reader.Name);
                if (reader.Name == "ImageBrush")
                {
                    //got some info before
                    Debug.Log("0: " + reader.GetAttribute(0));
                    Debug.Log("1: " + reader.GetAttribute(1));
                    Debug.Log("2: " + reader.GetAttribute(2));
                    Debug.Log("3: " + reader.GetAttribute(3));
                    Debug.Log("4: " + reader.GetAttribute(4));



                    string[] dimensions = reader.GetAttribute(2).Split(',');

                    SpriteX = int.Parse(dimensions[0]);
                    SpriteY = int.Parse(dimensions[1]);
                    SpriteWidth = int.Parse(dimensions[2]);
                    SpriteHeight = int.Parse(dimensions[3]);

                    //SpriteY = int.Parse(reader.GetAttribute(2));
                    //spriteHeight = int.Parse(reader.GetAttribute(4));

                    //create rect of sprite
                    rect = new Rect(
                        SpriteX, //x
                        imageHeight - SpriteY - SpriteHeight, //y imageHeight - SpriteY - spriteHeight
                        SpriteWidth, //width
                        SpriteHeight //hegith
                        );

                    //init spritedata
                    spritedata = new SpriteMetaData();
                    spritedata.rect = rect;
                    spritedata.name = reader.GetAttribute(0);
                    spritedata.alignment = (int)pivot;
                    if (pivot == SpriteAlignment.Custom)
                    {
                        spritedata.pivot = customPivot;
                    }
                    //add to list
                    listSprite.Add(spritedata);
                }
            }
        }

        //was sucessfull?
        if (listSprite.Count > 0)
        {
            //import texture
            TextureImporter textImp = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture2d)) as TextureImporter;
            //add spritesheets
            textImp.spritesheet = listSprite.ToArray();
            //configure texture
            textImp.textureType = TextureImporterType.Sprite;
            textImp.spriteImportMode = SpriteImportMode.Multiple;
            //import, for forceupdate and save it
            AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(texture2d), ImportAssetOptions.ForceUpdate);
            //Debug.Log("Done");
        }
        else
        {
            Debug.LogWarning("This is not a file of ShoeBox or is not a XML file");
        }
    }
}

 
User avatar
jsantos
Site Admin
Posts: 3905
Joined: 20 Jan 2012, 17:18
Contact:

Re: Shoebox converter and unity importer

14 Sep 2016, 21:39

This is so COOL! : D

Could you create a pull-request for adding it into noesisgui-contrib ?

Thanks a lot for this.
 
Etana
Topic Author
Posts: 17
Joined: 21 Aug 2016, 13:14

Re: Shoebox converter and unity importer

15 Sep 2016, 12:10

I have never used github pull-requests so I wonder if I messed something up.
I messed readme formatting twice so there is two useless commits on there but I hope that does not matter in this case.
My github username is zurra and there now should be pull-request in noesisgui-contrib.
 
User avatar
jsantos
Site Admin
Posts: 3905
Joined: 20 Jan 2012, 17:18
Contact:

Re: Shoebox converter and unity importer

16 Sep 2016, 06:21

Merged!

Thanks again for this contribution.

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 86 guests