码迷,mamicode.com
首页 > 编程语言 > 详细

unity资源texturepack导入和拆图-plist2sprite

时间:2015-01-22 13:08:12      阅读:3269      评论:0      收藏:0      [点我收藏+]

标签:

一.plist导出unity sprite图集

  texturepack有开源的工具可以导出json文件,然后倒入sprite。但是很多游戏使用的是plist打包,比如cocos2d。我们做demo可能需要这些资源来用用。所以有此需求。

  首先是解析plist。自己xml解析是在麻烦,网上找到个,使用c#的XDocument类,解析成自己的plist类型。代码基本没变,因为plist的<!DOCTYPE>那行总是解析出错,所以在外面载入好字符串,然后去掉这一行。

public void LoadText(string text)
{
Clear();
XDocument doc = XDocument.Parse(text);
XElement plist = doc.Element("plist");
XElement dict = plist.Element("dict");


var dictElements = dict.Elements();
Parse(this, dictElements);
}

  然后读取数据载入到自己的TPAtlas类里面(本来想通过这个类,直接缓存读取),然后是写入到textureImporter.spritesheet里,再AssetDatabase.ImportAsset就OK。这里有个问题,就设置sheet后,要重写textureType和spriteImportMode后面ImportAsset才有效,不然内存是改了,但是不会保存到meta文件,下次打开就没了,可能是unity的bug

[MenuItem("Assets/Texture/PLisToSprites(SelectPList)")]
    static void ConvertSprite()
    {
        //EditorUtility.DisplayDialog("MyTool", "Do It in C# !", "OK", "");
        Object selobj = Selection.activeObject;
        string selectionPath = AssetDatabase.GetAssetPath(Selection.activeObject);
        if (!selectionPath.EndsWith(".plist"))
        {
            EditorUtility.DisplayDialog("Error", "Please select a plist file!", "OK", "");
            return;
        }

        Debug.LogWarning("#PLisToSprites start:" + selectionPath);
        string fileContent = string.Empty;
        using (FileStream file = new FileStream(selectionPath, FileMode.Open))
        {
            byte[] str = new byte[(int)file.Length];
            file.Read(str, 0, str.Length);
            fileContent = GetUTF8String(str);
            Debug.Log(fileContent);
            file.Close();
            file.Dispose();
        }
        //去掉<!DOCTYPE>,不然异常
        int delStart = fileContent.IndexOf("<!DOCTYPE");
        int delEnd = fileContent.IndexOf("\n", delStart);
        fileContent = fileContent.Remove(delStart, delEnd - delStart);
        Debug.Log(fileContent);
        //解析文件
        PList plist = new PList();
        plist.LoadText(fileContent);//Load(selectionPath);
        TPAtlas at = new TPAtlas();
        at.LoadX(plist);

        //重写meta
        string texPath = Path.GetDirectoryName(selectionPath) + "/" + at.realTextureFileName;
        Texture2D selTex = AssetDatabase.LoadAssetAtPath(texPath, typeof(Texture2D)) as Texture2D;
        Debug.Log("texture:" + texPath);
        Debug.Log("write texture:" + selTex.name+ "  size:"+selTex.texelSize);
        TextureImporter textureImporter = AssetImporter.GetAtPath(texPath) as TextureImporter;
        if (textureImporter.textureType != TextureImporterType.Sprite && textureImporter.textureType != TextureImporterType.Advanced)
        {
            EditorUtility.DisplayDialog("Error", "Texture‘type must be sprite or Advanced!", "OK", "");
            return;
        }
        if (textureImporter.spriteImportMode!=SpriteImportMode.Multiple)
        {
            EditorUtility.DisplayDialog("Error", "spriteImportMode must be Multiple!", "OK", "");
            return;
        }
        SpriteMetaData[] sheetMetas = new SpriteMetaData[at.sheets.Count];
        for (int i = 0; i < at.sheets.Count; i++)
        {
            var frameData = at.sheets[i];
            sheetMetas[i].alignment = 0;
            sheetMetas[i].border = new Vector4(0, 0, 0, 0);
            sheetMetas[i].name = frameData.name;
            sheetMetas[i].pivot = new Vector2(0.5f, 0.5f);
            sheetMetas[i].rect = new Rect(frameData.frame.x, at.size.y - frameData.frame.y -frameData.frame.height,
                frameData.frame.width,frameData.frame.height);//这里原点在左下角,y相反
            //Debug.Log("do sprite:" + frameData.name);
        }
        //textureImporter.spriteImportMode = SpriteImportMode.Multiple;
        textureImporter.spritesheet = sheetMetas;

        //save
        textureImporter.textureType = TextureImporterType.Sprite;       //bug?
        textureImporter.spriteImportMode = SpriteImportMode.Multiple;   //不加这两句会导致无法保存meta
        AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate);

        Debug.LogWarning("#PLisToSprites end:" + texPath);
    }

二.unity sprite图集拆分小图

  有些图是ui用unity的sprite做ui目前不太靠谱,所以我们还是使用ngui等插件自己打图,所以要拆分。

  还是使用万能的TextureImporter类,拿到sheet然后,每个sheet写入到新图片。



[MenuItem("Assets/Texture/Output Sprites(SelectTexture)")]
static void OutputSprite()
{
string selectionPath = AssetDatabase.GetAssetPath(Selection.activeObject);
Texture2D selTex = Selection.activeObject as Texture2D;
string rootPath = Path.GetDirectoryName(selectionPath) +"/"+ Selection.activeObject.name;
TextureImporter textureImporter = AssetImporter.GetAtPath(selectionPath) as TextureImporter;
//textureImporter.textureType = TextureImporterType.Advanced;
//textureImporter.isReadable = true;
Object[] selected = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
if (!Directory.Exists(rootPath))
Directory.CreateDirectory(rootPath);
Debug.Log("output dir :" + rootPath);
//foreach (var item in selected)
//{
// Sprite sprite = item as Sprite;
// if (sprite == null)
// return;
// string path = rootPath + "/" + sprite.name + ".png";
// Debug.Log("output :" + path);
// SaveSpriteToPNG(sprite, path);
//}


foreach (var spmeta in textureImporter.spritesheet)
{
string path = rootPath + "/" + spmeta.name + ".png";
string subDir = Path.GetDirectoryName(path);
if (!Directory.Exists(subDir))
{
Directory.CreateDirectory(subDir);
}
Debug.Log("output :" + path);
SavePriteToPNG_Meta(selTex, spmeta, path);
}
AssetDatabase.Refresh();
}


static bool SaveSpriteToPNG(Sprite sprite, string outPath)
{
// 创建单独的纹理
Texture2D tex = new Texture2D((int)sprite.rect.width, (int)sprite.rect.height, sprite.texture.format, false);
tex.SetPixels(sprite.texture.GetPixels((int)sprite.rect.xMin, (int)sprite.rect.yMin,
(int)sprite.rect.width, (int)sprite.rect.height));
tex.Apply();
// 写入成PNG文件
File.WriteAllBytes(outPath, tex.EncodeToPNG());
return true;
}


static bool SavePriteToPNG_Meta(Texture2D sourceImg,SpriteMetaData metaData, string outPath)
{
Texture2D myimage = new Texture2D((int)metaData.rect.width, (int)metaData.rect.height, sourceImg.format,false);
Color[] pixs = sourceImg.GetPixels((int)metaData.rect.x, (int)metaData.rect.y,(int)metaData.rect.width, (int)metaData.rect.height);
myimage.SetPixels(pixs);
myimage.Apply();

//AssetDatabase.CreateAsset(myimage, rootPath + "/" + image.name + "/" + metaData.name + ".PNG");
File.WriteAllBytes(outPath, myimage.EncodeToPNG());
return true;
}

 

代码工程:http://pan.baidu.com/s/1hLqYM

使用注意事项:

plist转sprite要选中plist文件右击操作。元图要改成sprite的multi格式。里面数据名字可能有区别,主要看texture的名字和每个子图的rect,我兼容了两种版本,有其他格式自己改代码吧。还有plist要改成utf8格式,utf8+有时候无效。

拆小图要选中png图右击操作。格式要改成rgba32,不压缩的,类型advanced ,勾上read/write enable。还有size不能小于元图大小。

unity资源texturepack导入和拆图-plist2sprite

标签:

原文地址:http://www.cnblogs.com/magicsea/p/4241120.html

(1)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!