您的位置:首页 > 移动开发 > Unity3D

unity资源texturepack导入和拆图-plist2sprite

2015-01-22 11:07 513 查看

一.plist导出unitysprite图集

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

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

publicvoidLoadText(stringtext)
{
Clear();
XDocumentdoc=XDocument.Parse(text);
XElementplist=doc.Element("plist");
XElementdict=plist.Element("dict");


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

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

[MenuItem("Assets/Texture/PLisToSprites(SelectPList)")]
staticvoidConvertSprite()
{
//EditorUtility.DisplayDialog("MyTool","DoItinC#!","OK","");
Objectselobj=Selection.activeObject;
stringselectionPath=AssetDatabase.GetAssetPath(Selection.activeObject);
if(!selectionPath.EndsWith(".plist"))
{
EditorUtility.DisplayDialog("Error","Pleaseselectaplistfile!","OK","");
return;
}

Debug.LogWarning("#PLisToSpritesstart:"+selectionPath);
stringfileContent=string.Empty;
using(FileStreamfile=newFileStream(selectionPath,FileMode.Open))
{
byte[]str=newbyte[(int)file.Length];
file.Read(str,0,str.Length);
fileContent=GetUTF8String(str);
Debug.Log(fileContent);
file.Close();
file.Dispose();
}
//去掉<!DOCTYPE>,不然异常
intdelStart=fileContent.IndexOf("<!DOCTYPE");
intdelEnd=fileContent.IndexOf("\n",delStart);
fileContent=fileContent.Remove(delStart,delEnd-delStart);
Debug.Log(fileContent);
//解析文件
PListplist=newPList();
plist.LoadText(fileContent);//Load(selectionPath);
TPAtlasat=newTPAtlas();
at.LoadX(plist);

//重写meta
stringtexPath=Path.GetDirectoryName(selectionPath)+"/"+at.realTextureFileName;
Texture2DselTex=AssetDatabase.LoadAssetAtPath(texPath,typeof(Texture2D))asTexture2D;
Debug.Log("texture:"+texPath);
Debug.Log("writetexture:"+selTex.name+"size:"+selTex.texelSize);
TextureImportertextureImporter=AssetImporter.GetAtPath(texPath)asTextureImporter;
if(textureImporter.textureType!=TextureImporterType.Sprite&&textureImporter.textureType!=TextureImporterType.Advanced)
{
EditorUtility.DisplayDialog("Error","Texture'typemustbespriteorAdvanced!","OK","");
return;
}
if(textureImporter.spriteImportMode!=SpriteImportMode.Multiple)
{
EditorUtility.DisplayDialog("Error","spriteImportModemustbeMultiple!","OK","");
return;
}
SpriteMetaData[]sheetMetas=newSpriteMetaData[at.sheets.Count];
for(inti=0;i<at.sheets.Count;i++)
{
varframeData=at.sheets[i];
sheetMetas[i].alignment=0;
sheetMetas[i].border=newVector4(0,0,0,0);
sheetMetas[i].name=frameData.name;
sheetMetas[i].pivot=newVector2(0.5f,0.5f);
sheetMetas[i].rect=newRect(frameData.frame.x,at.size.y-frameData.frame.y-frameData.frame.height,
frameData.frame.width,frameData.frame.height);//这里原点在左下角,y相反
//Debug.Log("dosprite:"+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("#PLisToSpritesend:"+texPath);
}


二.unitysprite图集拆分小图

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

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



[MenuItem("Assets/Texture/OutputSprites(SelectTexture)")]
staticvoidOutputSprite()
{
stringselectionPath=AssetDatabase.GetAssetPath(Selection.activeObject);
Texture2DselTex=Selection.activeObjectasTexture2D;
stringrootPath=Path.GetDirectoryName(selectionPath)+"/"+Selection.activeObject.name;
TextureImportertextureImporter=AssetImporter.GetAtPath(selectionPath)asTextureImporter;
//textureImporter.textureType=TextureImporterType.Advanced;
//textureImporter.isReadable=true;
Object[]selected=Selection.GetFiltered(typeof(Object),SelectionMode.DeepAssets);
if(!Directory.Exists(rootPath))
Directory.CreateDirectory(rootPath);
Debug.Log("outputdir:"+rootPath);
//foreach(variteminselected)
//{
//Spritesprite=itemasSprite;
//if(sprite==null)
//return;
//stringpath=rootPath+"/"+sprite.name+".png";
//Debug.Log("output:"+path);
//SaveSpriteToPNG(sprite,path);
//}


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


staticboolSaveSpriteToPNG(Spritesprite,stringoutPath)
{
//创建单独的纹理
Texture2Dtex=newTexture2D((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());
returntrue;
}


staticboolSavePriteToPNG_Meta(Texture2DsourceImg,SpriteMetaDatametaData,stringoutPath)
{
Texture2Dmyimage=newTexture2D((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());
returntrue;
}



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

使用注意事项:

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

拆小图要选中png图右击操作。格式要改成rgba32,不压缩的,类型advanced,勾上read/writeenable。还有size不能小于元图大小。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: