注:一些代码是在网上找的,太多就没有写。

前几天做项目,遇到所要用的的大量图片都必须从网上下载,当时用的NGUI做的UI界面,当时上网找了好多,都不行,最后找一篇还差不多,但是也不好用,我重新捋了一遍;

首先,我想到的就是用NGUI的UITexture组件的UITexture.mainTexture来直接将WWW获取的图片给赋值上去,这样很简单,但是有新的问题,图片量比较大,如果图片少的话可以使用这种方法。

其次,换UI界面了,用UGUI做,UGUI是自动打图集,所以说方便,也可以用一两个RawTexture,但是UGUI要显示图片,必须将图片转换成Sprite,这也是一个难点,但是能够解决,可以将WWW 获取的图片用代码转换成Sprite格式,(转换这篇博客就不说了,下一篇我在说一下,有不会的可以看一看)。

最后,就是本博客的主要内容;NGUI动态打图集:

研究了好长时间,这种方法的只能是将图集打出来,但是不能弄成预设,图集打在一个空的GameObject上面,直接上代码:

usingUnityEngine;usingSystem.Collections;usingSystem.Collections.Generic;publicclassNGUIAtlasMaker:MonoBehaviour{publicstaticboolatlasTrimming=true;publicstaticboolatlasPMA=false;publicstaticboolunityPacking=false;publicstaticintatlasPadding=1;publicstaticboolallow4096=true;//主要就是继承UISpriteData,我们要修改它的类型publicclassSpriteEntry:UISpriteData{//Spritetexture--originaltextureoratemporarytexturepublicTexture2Dtex;//WhetherthetextureistemporaryandshouldbedeletedpublicbooltemporaryTexture=false;}staticintCompare(SpriteEntrya,SpriteEntryb){if(a==null&&b!=null)return1;if(a!=null&&b==null)return-1;intaPixels=a.width*a.height;intbPixels=b.width*b.height;if(aPixels>bPixels)return-1;elseif(aPixels<bPixels)return1;return0;}//对于Android和IOS是不一样的staticboolPackTextures(Texture2Dtex,List<SpriteEntry>sprites){Texture2D[]textures=newTexture2D[sprites.Count];Rect[]rects;#ifUNITY_3_5||UNITY_4_0intmaxSize=4096;#elseintmaxSize=SystemInfo.maxTextureSize;#endif#ifUNITY_ANDROID||UNITY_IPHONEmaxSize=Mathf.Min(maxSize,allow4096?4096:2048);#endifif(unityPacking){for(inti=0;i<sprites.Count;++i)textures[i]=sprites[i].tex;rects=tex.PackTextures(textures,atlasPadding,maxSize);}else{sprites.Sort(Compare);for(inti=0;i<sprites.Count;++i)textures[i]=sprites[i].tex;rects=UITexturePacker.PackTextures(tex,textures,4,4,atlasPadding,maxSize);}for(inti=0;i<sprites.Count;++i){Rectrect=NGUIMath.ConvertToPixels(rects[i],tex.width,tex.height,true);if(Mathf.RoundToInt(rect.width)!=textures[i].width)returnfalse;SpriteEntryse=sprites[i];se.x=Mathf.RoundToInt(rect.x);se.y=Mathf.RoundToInt(rect.y);se.width=Mathf.RoundToInt(rect.width);se.height=Mathf.RoundToInt(rect.height);}returntrue;}staticpublicvoidAddOrUpdate(UIAtlasatlas,Texture2Dtex){if(atlas!=null&&tex!=null){List<Texture>textures=newList<Texture>();textures.Add(tex);List<SpriteEntry>sprites=CreateSprites(textures);ExtractSprites(atlas,sprites);UpdateAtlas(atlas,sprites);}}staticpublicvoidUpdateAtlas(UIAtlasatlas,List<SpriteEntry>sprites){if(sprites.Count>0){if(UpdateTexture(atlas,sprites)){//ReplacethespriteswithintheatlasReplaceSprites(atlas,sprites);}//ReleasethetemporarytexturesReleaseSprites(sprites);return;}else{atlas.spriteList.Clear();NGUITools.Destroy(atlas.spriteMaterial.mainTexture);atlas.spriteMaterial.mainTexture=null;}atlas.MarkAsChanged();}///<summary>///Addanewspritetotheatlas,giventhetextureit'scomingfromandthepackedrectwithintheatlas.///</summary>staticpublicUISpriteDataAddSprite(List<UISpriteData>sprites,SpriteEntryse){//Seeifthisspritealreadyexistsforeach(UISpriteDataspinsprites){if(sp.name==se.name){sp.CopyFrom(se);returnsp;}}UISpriteDatasprite=newUISpriteData();sprite.CopyFrom(se);sprites.Add(sprite);returnsprite;}///<summary>///Createalistofspritesusingthespecifiedlistoftextures.///</summary>///staticpublicList<SpriteEntry>CreateSprites(List<Texture>textures){List<SpriteEntry>list=newList<SpriteEntry>();foreach(Texturetexintextures){Texture2DoldTex=texasTexture2D;//Ifwearen'tdoingtrimming,justusethetextureas-isif(!atlasTrimming&&!atlasPMA){SpriteEntrysprite=newSpriteEntry();sprite.SetRect(0,0,oldTex.width,oldTex.height);sprite.tex=oldTex;sprite.name=oldTex.name;sprite.temporaryTexture=false;list.Add(sprite);continue;}//Ifwewanttotrimtransparentpixels,thereismoreworktobedoneColor32[]pixels=oldTex.GetPixels32();intxmin=oldTex.width;intxmax=0;intymin=oldTex.height;intymax=0;intoldWidth=oldTex.width;intoldHeight=oldTex.height;//Findsolidpixelsif(atlasTrimming){for(inty=0,yw=oldHeight;y<yw;++y){for(intx=0,xw=oldWidth;x<xw;++x){Color32c=pixels[y*xw+x];if(c.a!=0){if(y<ymin)ymin=y;if(y>ymax)ymax=y;if(x<xmin)xmin=x;if(x>xmax)xmax=x;}}}}else{xmin=0;xmax=oldWidth-1;ymin=0;ymax=oldHeight-1;}intnewWidth=(xmax-xmin)+1;intnewHeight=(ymax-ymin)+1;if(newWidth>0&&newHeight>0){SpriteEntrysprite=newSpriteEntry();sprite.x=0;sprite.y=0;sprite.width=oldTex.width;sprite.height=oldTex.height;//Ifthedimensionsmatch,thennothingwasactuallytrimmedif(!atlasPMA&&(newWidth==oldWidth&&newHeight==oldHeight)){sprite.tex=oldTex;sprite.name=oldTex.name;sprite.temporaryTexture=false;}else{//Copythenon-trimmedtexturedataintoatemporarybufferColor32[]newPixels=newColor32[newWidth*newHeight];for(inty=0;y<newHeight;++y){for(intx=0;x<newWidth;++x){intnewIndex=y*newWidth+x;intoldIndex=(ymin+y)*oldWidth+(xmin+x);if(atlasPMA)newPixels[newIndex]=NGUITools.ApplyPMA(pixels[oldIndex]);elsenewPixels[newIndex]=pixels[oldIndex];}}//Createanewtexturesprite.temporaryTexture=true;sprite.name=oldTex.name;sprite.tex=newTexture2D(newWidth,newHeight);sprite.tex.SetPixels32(newPixels);sprite.tex.Apply();//Rememberthepaddingoffsetsprite.SetPadding(xmin,ymin,oldWidth-newWidth-xmin,oldHeight-newHeight-ymin);}list.Add(sprite);}}returnlist;}///<summary>///Releasealltemporarytexturescreatedforthesprites.///</summary>staticpublicvoidReleaseSprites(List<SpriteEntry>sprites){foreach(SpriteEntryseinsprites){if(se.temporaryTexture){NGUITools.Destroy(se.tex);se.tex=null;}}Resources.UnloadUnusedAssets();}staticpublicvoidReplaceSprites(UIAtlasatlas,List<SpriteEntry>sprites){//Getthelistofspriteswe'llbeupdatingList<UISpriteData>spriteList=atlas.spriteList;List<UISpriteData>kept=newList<UISpriteData>();//Runthroughallthetexturesweaddedandaddthemasspritestotheatlasfor(inti=0;i<sprites.Count;++i){SpriteEntryse=sprites[i];UISpriteDatasprite=AddSprite(spriteList,se);kept.Add(sprite);}//Removeunusedspritesfor(inti=spriteList.Count;i>0;){UISpriteDatasp=spriteList[--i];if(!kept.Contains(sp))spriteList.RemoveAt(i);}//Sortthespritessothattheyarealphabeticalwithintheatlasatlas.SortAlphabetically();atlas.MarkAsChanged();}///<summary>///Extractthespecifiedspritefromtheatlas.///</summary>///staticpublicSpriteEntryExtractSprite(UIAtlasatlas,stringspriteName){if(atlas.texture==null)returnnull;UISpriteDatasd=atlas.GetSprite(spriteName);if(sd==null)returnnull;Texture2Dtex=atlas.textureasTexture2D;SpriteEntryse=ExtractSprite(sd,tex);returnse;}///<summary>///Extractthespecifiedspritefromtheatlastexture.///</summary>staticSpriteEntryExtractSprite(UISpriteDataes,Texture2Dtex){return(tex!=null)?ExtractSprite(es,tex.GetPixels32(),tex.width,tex.height):null;}///<summary>///Extractthespecifiedspritefromtheatlastexture.///</summary>staticSpriteEntryExtractSprite(UISpriteDataes,Color32[]oldPixels,intoldWidth,intoldHeight){intxmin=Mathf.Clamp(es.x,0,oldWidth);intymin=Mathf.Clamp(es.y,0,oldHeight);intxmax=Mathf.Min(xmin+es.width,oldWidth-1);intymax=Mathf.Min(ymin+es.height,oldHeight-1);intnewWidth=Mathf.Clamp(es.width,0,oldWidth);intnewHeight=Mathf.Clamp(es.height,0,oldHeight);if(newWidth==0||newHeight==0)returnnull;Color32[]newPixels=newColor32[newWidth*newHeight];for(inty=0;y<newHeight;++y){intcy=ymin+y;if(cy>ymax)cy=ymax;for(intx=0;x<newWidth;++x){intcx=xmin+x;if(cx>xmax)cx=xmax;intnewIndex=(newHeight-1-y)*newWidth+x;intoldIndex=(oldHeight-1-cy)*oldWidth+cx;newPixels[newIndex]=oldPixels[oldIndex];}}//CreateanewspriteSpriteEntrysprite=newSpriteEntry();sprite.CopyFrom(es);sprite.SetRect(0,0,newWidth,newHeight);sprite.temporaryTexture=true;sprite.tex=newTexture2D(newWidth,newHeight);sprite.tex.SetPixels32(newPixels);sprite.tex.Apply();returnsprite;}///<summary>///Extractspritesfromtheatlas,addingthemtothelist.///</summary>staticpublicvoidExtractSprites(UIAtlasatlas,List<SpriteEntry>finalSprites){Texture2Dtex=atlas.textureasTexture2D;if(tex!=null){Color32[]pixels=null;intwidth=tex.width;intheight=tex.height;List<UISpriteData>sprites=atlas.spriteList;floatcount=sprites.Count;intindex=0;foreach(UISpriteDataesinsprites){boolfound=false;foreach(SpriteEntryfsinfinalSprites){if(es.name==fs.name){fs.CopyBorderFrom(es);found=true;break;}}if(!found){if(pixels==null)pixels=tex.GetPixels32();SpriteEntrysprite=ExtractSprite(es,pixels,width,height);if(sprite!=null)finalSprites.Add(sprite);}}}}staticpublicboolUpdateTexture(UIAtlasatlas,List<SpriteEntry>sprites){//GetthetexturefortheatlasTexture2Dtex=atlas.textureasTexture2D;boolnewTexture=tex==null;if(newTexture){//Createanewtexturefortheatlastex=newTexture2D(1,1,TextureFormat.ARGB32,false);}//Packthespritesintothistextureif(PackTextures(tex,sprites)&&tex!=null){//Updatetheatlastextureif(newTexture){if(atlas.spriteMaterial==null){Shadershader=Shader.Find(atlasPMA?"Unlit/PremultipliedColored":"Unlit/TransparentColored");atlas.spriteMaterial=newMaterial(shader);}atlas.spriteMaterial.mainTexture=tex;ReleaseSprites(sprites);}returntrue;}else{returnfalse;}}//saveasngui'spublicUITexturePacker(intwidth,intheight,boolrotations){Init(width,height,rotations);}publicvoidInit(intwidth,intheight,boolrotations){binWidth=width;binHeight=height;allowRotations=rotations;Rectn=newRect();n.x=0;n.y=0;n.width=width;n.height=height;usedRectangles.Clear();freeRectangles.Clear();freeRectangles.Add(n);}privatestructStorage{publicRectrect;publicboolpaddingX;publicboolpaddingY;}publicstaticRect[]PackTextures(Texture2Dtexture,Texture2D[]textures,intwidth,intheight,intpadding,intmaxSize){if(width>maxSize&&height>maxSize)returnnull;if(width>maxSize||height>maxSize){inttemp=width;width=height;height=temp;}//Forcesquarebysizingup//szmodify//if(NGUISettings.forceSquareAtlas)if(forceSquareAtlas){if(width>height)height=width;elseif(height>width)width=height;}UITexturePackerbp=newUITexturePacker(width,height,false);Storage[]storage=newStorage[textures.Length];for(inti=0;i<textures.Length;i++){Texture2Dtex=textures[i];if(!tex)continue;Rectrect=newRect();intxPadding=1;intyPadding=1;for(xPadding=1;xPadding>=0;--xPadding){for(yPadding=1;yPadding>=0;--yPadding){rect=bp.Insert(tex.width+(xPadding*padding),tex.height+(yPadding*padding),UITexturePacker.FreeRectChoiceHeuristic.RectBestAreaFit);if(rect.width!=0&&rect.height!=0)break;//Afterhavingnopaddingifitstilldoesn'tfit--increasetexturesize.elseif(xPadding==0&&yPadding==0){returnPackTextures(texture,textures,width*(width<=height?2:1),height*(height<width?2:1),padding,maxSize);}}if(rect.width!=0&&rect.height!=0)break;}storage[i]=newStorage();storage[i].rect=rect;storage[i].paddingX=(xPadding!=0);storage[i].paddingY=(yPadding!=0);}texture.Resize(width,height);texture.SetPixels(newColor[width*height]);//ThereturnedrectsRect[]rects=newRect[textures.Length];for(inti=0;i<textures.Length;i++){Texture2Dtex=textures[i];if(!tex)continue;Rectrect=storage[i].rect;intxPadding=(storage[i].paddingX?padding:0);intyPadding=(storage[i].paddingY?padding:0);Color[]colors=tex.GetPixels();//Wouldbeusedtorotatethetextureifneedbe.if(rect.width!=tex.width+xPadding){Color[]newColors=tex.GetPixels();for(intx=0;x<rect.width;x++){for(inty=0;y<rect.height;y++){intprevIndex=((int)rect.height-(y+1))+x*(int)tex.width;newColors[x+y*(int)rect.width]=colors[prevIndex];}}colors=newColors;}texture.SetPixels((int)rect.x,(int)rect.y,(int)rect.width-xPadding,(int)rect.height-yPadding,colors);rect.x/=width;rect.y/=height;rect.width=(rect.width-xPadding)/width;rect.height=(rect.height-yPadding)/height;rects[i]=rect;}texture.Apply();returnrects;}。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。代码量挺大,我就不全写出来了,如果要深入研究,可以下载附件,这个脚本只是一个要被调用的脚本。}下面就是我们要调用的参数:usingUnityEngine;usingSystem.Collections;publicclassNGUIAtlasMakerTest:MonoBehaviour{publicUITexturett;privateTexture[]img;privateTexture2D[]texs;publicUISpritesprite;privateUIAtlasatlas;voidStart(){StartCoroutine(GetTupian());Invoke("TokeImage",3.0f);}//此方法就是调用打图集的方法publicvoidTokeImage(){//将下载的图片存储到texs中,进行动态打图集texs=newTexture2D[img.Length];for(inti=0;i<img.Length;i++){texs[i]=img[i]asTexture2D;}NGUIAtlasMaker.atlasTrimming=true;NGUIAtlasMaker.atlasPMA=atlas!=null?atlas.premultipliedAlpha:false;NGUIAtlasMaker.unityPacking=false;NGUIAtlasMaker.atlasPadding=1;NGUIAtlasMaker.allow4096=true;NGUIAtlasMaker.UITexturePacker.forceSquareAtlas=true;if(atlas==null){atlas=this.gameObject.AddComponent<UIAtlas>();}stringlastName=string.Empty;foreach(vartexintexs){SZUIAtlasMakerRuntime.AddOrUpdate(atlas,tex);lastName=tex.name;}sprite.atlas=atlas;sprite.spriteName=lastName;}//图片下载过程(注意:我在这里只下载了一张图片,根据需要,你可以下载多张,只要存储到img数组或者texs数组中就行)这些都是很简单了,但是下载的图片是没有名字的,我想了个办法给命名了,IEnumeratorGetTupian(){Debug.Log(1212);WWWwww=newWWW("https://cache.yisu.com/upload/information/20200310/64/129671.jpg");yieldreturnwww;Texture2Dtu=//命名的过程tu.name="ttt";Debug.Log(www.texture.name);img=newTexture[1];for(inti=0;i<img.Length;i++){img[i]=tu;}tt.mainTexture=img[0];}这种动态打图集,只能将图集打到一个空的GameObject上,,也就是说GameObject就是一个图集,但却不是预设,如果大家有什么好的建议或者方法,都可以分享出来,或者联系我


附件:http://down.51cto.com/data/2367292