请先看一下帖子:http://www.unitymanual.com/thread-16004-1-1.html
这帖子的第一种方法其实已经说明了如何在程序中创建图集,只不过他这里是使用一张图片做成图集,再给UISprite控件使用。
==================================================================
public class ImageLoader : MonoBehaviour {
sprite.outer = sprite.inner = new Rect(0f, 0f, tex.width, tex.height);
m_uiAtlas.spriteList.Clear();
m_uiAtlas.spriteList.Add(sprite);
//设置完成
m_img.atlas = m_uiAtlas;
m_img.spriteName = tex.name;
}
}
============================================================
我们工作中常常遇到的是需要将多张图片制作成一个图集,再给多个UISprite控件使用,其实看懂了上面的代码运行时如何生成图集,再结合平常在编辑器中制作图集,答案就已经出来了。请大家好好看看NGUI的编辑器脚本UIAtlasMaker,也就是我们平常在编辑器中制作图集时用的脚本。我们缺少的仅仅是将多张图片PackTextures(打包)成一张大图(也就是我们的图集啦),其实UIAtlasMaker脚本那么长,核心的操作也就是为了PackTextures,也就是unity3d的API里Texture2D.PackTextures函数,这里大家可以参考我以前转的别人的一篇关于该函数用法的文章:http://blog.sina.com.cn/s/blog_930ffa0b0102uyl8.html
和一篇别人分析UIAtlasMaker脚本的文章:http://dsqiu.iteye.com/blog/1967088
好了,最后就是我将UIAtlasMaker脚本里打包操作的函数拔出来后的工具类了,只有CreatAtlasFromTex这一个对外使用的函数。使用时只需要传人个UIAtlas组件和图片LIST就可以了,图集生成好后,UISprite控件就可以使用该动态图集了,这样好多个UISprite控件组成的下拉列表项只占一个DrawCall。
=============================CreatAtlas.cs=============================
using UnityEngine;
using System.Collections.Generic;
///
/// 运行时创建NGUI图集,NGUI2.6.3
///
public static class CreatAtlas {
class SpriteEntry {
public Texture2D tex; // Sprite texture -- original texture or a temporary texture
public Rect rect; // Sprite's outer rectangle within the generated texture atlas
public int minX = 0; // Padding, if any (set if the sprite is trimmed)
public int maxX = 0;
public int minY = 0;
public int maxY = 0;
public bool temporaryTexture = false; // Whether the texture is temporary and should be deleted
}
static Shader s_shader = Shader.Find("Unlit/Transparent Colored");
static Material s_mat = new Material(s_shader);
static int s_maximumAtlasSize = 2048;
static TextureFormat s_TextureFormat = TextureFormat.RGBA32;
static List CreateSprites (List textures) {
List list = new List( );
foreach (Texture tex in textures) {
Texture2D oldTex = tex as Texture2D;
if (oldTex == null) continue;
// If we want to trim transparent pixels, there is more work to be done
Color32[ ] pixels = oldTex.GetPixels32( );
int xmin = oldTex.width;
int xmax = 0;
int ymin = oldTex.height;
int ymax = 0;
int oldWidth = oldTex.width;
int oldHeight = oldTex.height;
// Find solid pixels
for (int y = 0, yw = oldHeight; y < yw; ++y) {
for (int x = 0, xw = oldWidth; x < xw; ++x) {
Color32 c = 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;
}
}
}
int newWidth = (xmax - xmin) + 1;
int newHeight = (ymax - ymin) + 1;
// If the sprite is empty, don't do anything with it
if (newWidth > 0 && newHeight > 0) {
SpriteEntry sprite = new SpriteEntry( );
sprite.rect = new Rect(0f, 0f, oldTex.width, oldTex.height);
// If the dimensions match, then nothing was actually trimmed
if (newWidth == oldWidth && newHeight == oldHeight) {
sprite.tex = oldTex;
sprite.temporaryTexture = false;
} else {
// Copy the non-trimmed texture data into a temporary buffer
Color32[ ] newPixels = new Color32[newWidth * newHeight];
for (int y = 0; y < newHeight; ++y) {
for (int x = 0; x < newWidth; ++x) {
int newIndex = y * newWidth + x;
int oldIndex = (ymin + y) * oldWidth + (xmin + x);
newPixels[newIndex] = pixels[oldIndex];
}
}
// Create a new texture
sprite.temporaryTexture = true;
sprite.tex = new Texture2D(newWidth, newHeight);
sprite.tex.name = oldTex.name;
sprite.tex.SetPixels32(newPixels);
sprite.tex.Apply( );
for (int i = 0; i < sprites.Count; ++i) {
sprites.rect = NGUIMath.ConvertToPixels(rects, tex.width, tex.height, true);
}
}
static void ReplaceSprites (UIAtlas atlas, List sprites) {
// Get the list of sprites we'll be updating
List spriteList = atlas.spriteList;
List kept = new List( );
// The atlas must be in pixels
atlas.coordinates = UIAtlas.Coordinates.Pixels;
// Run through all the textures we added and add them as sprites to the atlas
for (int i = 0; i < sprites.Count; ++i) {
SpriteEntry se = sprites;
UIAtlas.Sprite sprite = AddSprite(spriteList, se);
kept.Add(sprite);
}
// Remove unused sprites
for (int i = spriteList.Count; i > 0; ) {
UIAtlas.Sprite sp = spriteList[--i];
if (!kept.Contains(sp)) spriteList.RemoveAt(i);
}
atlas.MarkAsDirty( );
}