Programatically adding to a multi-sprite from editor script

I want to be able to create all the child sprites of a multi-sprite from script but I’m not sure how to do it.

Here’s what I’ve got so far:

Texture2D tex = Selection.activeObject as Texture2D;
if(tex == null){
	Debug.Log ("Not a texture. You can't make a sprite sheet out of a " + Selection.activeObject.GetType().ToString());
	return;
}

string texPath = AssetDatabase.GetAssetPath(tex);

TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(texPath);
if(importer.textureType != TextureImporterType.Sprite || importer.spriteImportMode != SpriteImportMode.Multiple){
	if(EditorUtility.DisplayDialog("Not A Multi-Sprite", "Image is not a multi-sprite. Do you want to make it one?", "Yup", "Nope")){
		importer.textureType = TextureImporterType.Sprite;
		importer.spriteImportMode = SpriteImportMode.Multiple;
		AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate);
	}
	else
		return;
}


//It all works up till this point. Setting the importer.spritesheet doesn't seem to do anything.
List<SpriteMetaData> spriteList = new List<SpriteMetaData>();

for(int i=0; i<4; i++){
	SpriteMetaData meta = new SpriteMetaData();
	meta.name = "Sprite" + i.ToString();
	meta.rect = new Rect(i * 10, 10, 10, 10);
        meta.pivot = new Vector2(0.25f, 0.25f);
	spriteList.Add (meta);
}

importer.spritesheet = spriteList.ToArray();
EditorUtility.SetDirty(tex);

UPDATE:
So setting the importer.spritesheet does actually work but you have to open the sprite editor edit one of the sprites then hit Apply before the sprites get generated. Anybody know of a way to manually generate all the sprites from the spritesheet?

UPDATE 2:
Even if I do generate the sprites by going in, editing and hitting apply (See Update 1) then the pivot that I set in the for-loop isn’t coming across.

So I’ve got almost everything working how I want. I can generate a Sparrow sprite sheet from Flash which gives me a texture and an xml file. I then read that xml file and create all the sprites and position them and set their pivots and all that. Working as expected.

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Xml;

public class AnimSpriteMaker : Editor {

	[MenuItem("Assets/Convert To Sprite Sheet")]
	public static void Make () {
		Texture2D tex = Selection.activeObject as Texture2D;
		if(tex == null){
			Debug.Log ("Not a texture. You can't make a sprite sheet out of a " + Selection.activeObject.GetType().ToString());
			return;
		}

		string path = Application.dataPath;
		path = path.Replace("Assets", "ContentSource/Art/Characters");
		string xmlFile = EditorUtility.OpenFilePanel("Sprite Info", path, "xml");
		if(string.IsNullOrEmpty(xmlFile))
			return;

		XmlDocument xDoc = new XmlDocument();
		xDoc.Load(xmlFile);

		XmlNode atlas = xDoc.LastChild;
		string imageName = atlas.Attributes.GetNamedItem("imagePath").Value;

		if(imageName.IndexOf(tex.name) == -1){
			if(!EditorUtility.DisplayDialog("Wrong Image?", "The image name doesn't match the image in the xml file. Continue anyway?", "Yup", "Nope"))
				return;
		}

		string texPath = AssetDatabase.GetAssetPath(tex);

		TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(texPath);
		if(importer.textureType != TextureImporterType.Sprite || importer.spriteImportMode != SpriteImportMode.Multiple){
			if(EditorUtility.DisplayDialog("Not A Multi-Sprite", "Image is not a multi-sprite. Do you want to make it one?", "Yup", "Nope")){
				importer.textureType = TextureImporterType.Sprite;
				importer.spriteImportMode = SpriteImportMode.Multiple;
				AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate);
			}
			else
				return;
		}

		List<SpriteMetaData> spriteList = new List<SpriteMetaData>();

		float px = 0, py = 0;

		for(int i=0; i<atlas.ChildNodes.Count; i++){
			XmlNode node = atlas.ChildNodes[i];
			if(node.Name == "SubTexture"){
				SpriteMetaData meta = new SpriteMetaData();
				meta.name = node.Attributes.GetNamedItem("name").Value;

				float x, y, w, h;
				float.TryParse(node.Attributes.GetNamedItem("x").Value, out x);
				float.TryParse(node.Attributes.GetNamedItem("y").Value, out y);
				float.TryParse(node.Attributes.GetNamedItem("width").Value, out w);
				float.TryParse(node.Attributes.GetNamedItem("height").Value, out h);

				y = tex.height - y - h;

				meta.rect = new Rect(x, y, w, h);
				float oldPY = py;
				XmlNode pivotXNode = node.Attributes.GetNamedItem("pivotX");
				XmlNode pivotYNode = node.Attributes.GetNamedItem("pivotY");
				if(pivotXNode != null  pivotYNode != null){
					float.TryParse(pivotXNode.Value, out px);
					float.TryParse(pivotYNode.Value, out py);
				}

				if(oldPY != py){
					oldPY = py;
					Debug.Log (meta.name);
				}

				float fx, fy, fw, fh;
				float.TryParse(node.Attributes.GetNamedItem("frameX").Value, out fx);
				float.TryParse(node.Attributes.GetNamedItem("frameY").Value, out fy);
				float.TryParse(node.Attributes.GetNamedItem("frameWidth").Value, out fw);
				float.TryParse(node.Attributes.GetNamedItem("frameHeight").Value, out fh);


				float vx = w-fx;
				vx -= px;
				vx = w - vx;
				vx /= w;

				float vy = h-fy;
				vy -= py;
				vy = h - vy;
				vy /= h;

				meta.alignment = 9;
				meta.pivot = new Vector2(vx, 1-vy);

				spriteList.Add (meta);
			}
		}

		importer.spritesheet = spriteList.ToArray();
	}
}

The only problem is that after I run this I have to open the Sprite Editor window, do something (Selecting a sprite and deleting then re-entering one of the position fields works), then apply becomes available and I hit apply and yay its done.

I want to be able to skip that last part… Any ideas?

If you are still interested, I managed it to refresh with adding these:

EditorUtility.SetDirty(textureImporter);
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);