动态图集的意义
比如说MOBA类游戏,在进入对战场景时,我们需要选择英雄,配置技能,选择天赋和符文等,这些图标如果都事先打好了图集,在对战场景就会加载很多没有用的图标,而如果不打图集,就会增加很多drawcall,所以我们需要动态生成图集。
动态图集算法
GitHub - DaVikingCode/UnityRuntimeSpriteSheetsGenerator: Unity – generate SpriteSheets at runtime!
Unity也提供了算法Unity - Scripting API: Texture2D.PackTextures (unity3d.com)
我们使用GitHub的项目。
核心代码
AssetPacker
类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| public void AddTextureToPack(string file, string customID = null) {
itemsToRaster.Add(new TextureToPack(file, customID != null ? customID : Path.GetFileNameWithoutExtension(file))); }
public void AddTexturesToPack(string[] files) {
foreach (string file in files) AddTextureToPack(file); } public void Process(bool allow4096Textures = false) {
this.allow4096Textures = allow4096Textures;
if (useCache) {
if (cacheName == "") throw new Exception("No cache name specified");
string path = Application.persistentDataPath + "/AssetPacker/" + cacheName + "/" + cacheVersion + "/";
bool cacheExist = Directory.Exists(path);
if (!cacheExist) StartCoroutine(createPack(path)); else StartCoroutine(loadPack(path)); } else StartCoroutine(createPack()); } protected IEnumerator createPack(string savePath = "") {
if (savePath != "") { } List<Texture2D> textures = new List<Texture2D>(); List<string> images = new List<string>(); foreach (TextureToPack itemToRaster in itemsToRaster) {
WWW loader = new WWW("file:///" + itemToRaster.file);
yield return loader;
textures.Add(loader.texture); images.Add(itemToRaster.id); } int textureSize = allow4096Textures ? 4096 : 2048; List<Rect> rectangles = new List<Rect>(); while (rectangles.Count > 0) {
Texture2D texture = new Texture2D(textureSize, textureSize, TextureFormat.ARGB32, false); RectanglePacker packer = new RectanglePacker(texture.width, texture.height, padding); if (packer.rectangleCount > 0) { for (int j = 0; j < packer.rectangleCount; j++) { texture.SetPixels32(rect.x, rect.y, rect.width, rect.height, textures[index].GetPixels32()); } } } }
|
Texture2D.SetPixels32
方法需要Texture2D是可读可写的。
如果最后打出的文件是红色的,说明传入需要打图集的单个图片时没有加入后缀。