private static bool CanPackTexturesInSize(Texture2D[] textures, int size, int padding, UITexturePacker.FreeRectChoiceHeuristic heuristic) { using (var packer = new UITexturePackerSpec(size, size, false)) { for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) continue; Rect rect = new Rect(); int xPadding; int yPadding; for (xPadding = 1; xPadding >= 0; --xPadding) { for (yPadding = 1; yPadding >= 0; --yPadding) { rect = packer.Insert(tex.width + (xPadding*padding), tex.height + (yPadding*padding), heuristic); if (rect.width > 0 && rect.height > 0) break; // After having no padding if it still doesn't fit -- we can't pack all textures in this size. else if (xPadding == 0 && yPadding == 0) { return false; } } if (rect.width > 0 && rect.height > 0) break; } } } return true; }
/// <summary> /// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed. /// </summary> static void PackTextures(Texture2D tex, List <SpriteEntry> sprites) { Texture2D[] textures = new Texture2D[sprites.Count]; Rect[] rects; if (NGUISettings.unityPacking) { for (int i = 0; i < sprites.Count; ++i) { textures[i] = sprites[i].tex; } rects = tex.PackTextures(textures, NGUISettings.atlasPadding, 4096); } else { sprites.Sort(Compare); for (int i = 0; i < sprites.Count; ++i) { textures[i] = sprites[i].tex; } rects = UITexturePacker.PackTextures(tex, textures, 4, 4, NGUISettings.atlasPadding, 4096); } for (int i = 0; i < sprites.Count; ++i) { sprites[i].rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true); //BleedTexture(tex, sprites[i].rect); } }
/// <summary> /// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed. /// </summary> static bool PackTextures(Texture2D tex, List <SpriteEntry> sprites) { Texture2D[] textures = new Texture2D[sprites.Count]; Rect[] rects; #if UNITY_3_5 || UNITY_4_0 int maxSize = 4096; #else int maxSize = SystemInfo.maxTextureSize; #endif #if UNITY_ANDROID || UNITY_IPHONE #if !UNITY_3_5 && !UNITY_4_0 if (PlayerSettings.targetGlesGraphics == TargetGlesGraphics.OpenGLES_1_x) { maxSize = Mathf.Min(maxSize, 1024); } else #endif { maxSize = Mathf.Min(maxSize, NGUISettings.allow4096 ? 4096 : 2048); } #endif if (NGUISettings.unityPacking) { for (int i = 0; i < sprites.Count; ++i) { textures[i] = sprites[i].tex; } rects = tex.PackTextures(textures, NGUISettings.atlasPadding, maxSize); } else { sprites.Sort(Compare); for (int i = 0; i < sprites.Count; ++i) { textures[i] = sprites[i].tex; } rects = UITexturePacker.PackTextures(tex, textures, 4, 4, NGUISettings.atlasPadding, maxSize); } for (int i = 0; i < sprites.Count; ++i) { Rect rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true); // Make sure that we don't shrink the textures if (Mathf.RoundToInt(rect.width) != textures[i].width) { return(false); } SpriteEntry se = 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); } return(true); }
public static int CreateUIAtlas(List<Texture2D> images, string atlasName, int? size, out int minSize, UITexturePacker.FreeRectChoiceHeuristic heuristic) { string selectionFolder = NGUIEditorTools.GetSelectionFolder(); if (string.IsNullOrEmpty(atlasName)) { var lastIndexOf = selectionFolder.Substring(0, selectionFolder.Length - 1).LastIndexOf("/"); atlasName = selectionFolder.Substring(lastIndexOf + 1, selectionFolder.Length - lastIndexOf - 2); } UIAtlas atlas; string prefabPath = AssetDatabase.GetAllAssetPaths().FirstOrDefault(x => x.EndsWith("/" + atlasName + ".prefab")); if (prefabPath == null) { prefabPath = selectionFolder + atlasName + ".prefab"; atlas = CreateAtlas(atlasName); } else { Debug.Log("Update existing"); atlas = AssetDatabase.LoadAssetAtPath(prefabPath, typeof (UIAtlas)) as UIAtlas; } Texture2D newTexture = UpdateUIAtlas(atlas, images, ref size, out minSize, heuristic); var texture = SaveTexture(prefabPath, newTexture); atlas.spriteMaterial.mainTexture = texture; EditorUtility.SetDirty(atlas); // Update the prefab AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Debug.Log("***************** All done - " + DateTime.Now); return size.Value; }
/// <summary> /// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed. /// </summary> static bool PackTextures(Texture2D tex, List <SpriteEntry> sprites) { var textures = new Texture2D[sprites.Count]; Rect[] rects; #if UNITY_3_5 || UNITY_4_0 int maxSize = 4096; #else var maxSize = SystemInfo.maxTextureSize; #endif #if UNITY_ANDROID || UNITY_IPHONE maxSize = Mathf.Min(maxSize, NGUISettings.allow4096 ? 4096 : 2048); #endif if (NGUISettings.unityPacking) { for (var i = 0; i < sprites.Count; ++i) { textures[i] = sprites[i].tex; } rects = tex.PackTextures(textures, NGUISettings.atlasPadding, maxSize); } else { sprites.Sort(Compare); for (var i = 0; i < sprites.Count; ++i) { textures[i] = sprites[i].tex; } rects = UITexturePacker.PackTextures(tex, textures, 4, 4, NGUISettings.atlasPadding, maxSize); } for (var i = 0; i < sprites.Count; ++i) { var rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true); // Apparently Unity can take the liberty of destroying temporary textures without any warning if (textures[i] == null) { return(false); } // Make sure that we don't shrink the textures if (Mathf.RoundToInt(rect.width) != textures[i].width) { return(false); } var se = 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); } return(true); }
/// <summary> /// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed. /// </summary> static void PackTextures(Texture2D tex, List <SpriteEntry> sprites) { Texture2D[] textures = new Texture2D[sprites.Count]; for (int i = 0; i < sprites.Count; ++i) { textures[i] = sprites[i].tex; } //Rect[] rects = tex.PackTextures(textures, 1, 4096); Rect[] rects = UITexturePacker.PackTextures(tex, textures, 4, 4, UISettings.atlasPadding, 4096); for (int i = 0; i < sprites.Count; ++i) { sprites[i].rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true); } }
{ //打包算法封装 public Rect[] Pack(Texture2D tex, Texture2D[] imgs, int padding, object config) { //打包纹理 Rect[] rects = null; #if UNITY_3_5 || UNITY_4_0 int maxSize = 4096; #else int maxSize = SystemInfo.maxTextureSize; #endif rects = UITexturePacker.PackTextures(tex, imgs, 4, 4, padding, maxSize); for (int i = 0; i < imgs.Length; ++i) { Rect rect = ConvertToPixels(rects[i], tex.width, tex.height, true); // Make sure that we don't shrink the textures if (Mathf.RoundToInt(rect.width) != imgs[i].width) { return(null); } } return(rects); }
/// <summary> /// Rebuilds the atlas texture. /// </summary> public void RebuildAtlas() { if (this.m_Instance == null) { Debug.LogError( "SPAtlasBuilder failed to rebuild the atlas, reason: Sprite Packer Instance reference is null."); return; } if (this.m_Instance.texture == null) { Debug.LogWarning( "Sprite Packer failed to rebuild the atlas, please make sure the atlas texture reference is set."); return; } // Make the atlas texture readable if (SPTools.TextureSetReadWriteEnabled(this.m_Instance.texture, true, false)) { // Get a list with the current sprites and applied actions List <SPSpriteInfo> spriteInfoList = this.m_Instance.GetSpriteListWithAppliedActions(); // Get the source textures asset paths string[] sourceTexturePaths = this.CollectSourceTextureAssetPaths(spriteInfoList); // Make the source textures readable if (!this.SetAssetsReadWriteEnabled(sourceTexturePaths, true)) { Debug.LogError( "Sprite Packer failed to make one or more of the source texture readable, please do it manually."); return; } // Make sure all the textures have the correct texture format this.CorrectTexturesFormat(spriteInfoList); // If we are using max rects packing, sort the sprite info list by size if (this.m_Instance.packingMethod == SPInstance.PackingMethod.MaxRects) { spriteInfoList.Sort(CompareBySize); } // Temporary textures array Texture2D[] textures = new Texture2D[spriteInfoList.Count]; // Create an array to contain the sprite import data SPSpriteImportData[] spritesImportData = new SPSpriteImportData[spriteInfoList.Count]; // Populate the textures and names arrays int ia = 0; foreach (SPSpriteInfo si in spriteInfoList) { // Temporary texture Texture2D texture = null; // Prepare the sprite import data SPSpriteImportData importData = new SPSpriteImportData(); // Prepare the sprite name importData.name = "Sprite_" + ia.ToString(); if (si.targetSprite != null) { importData.name = si.targetSprite.name; } else if (si.source != null && (si.source is Texture2D || si.source is Sprite)) { if (si.source is Texture2D) { importData.name = (si.source as Texture2D).name; } else { importData.name = (si.source as Sprite).name; } } // Prepare texture // In case the source texture is missing, rebuild from the already existing sprite if (si.source == null && si.targetSprite != null) { // Copy the sprite into the temporary texture texture = new Texture2D((int)si.targetSprite.rect.width, (int)si.targetSprite.rect.height, TextureFormat.ARGB32, false); Color[] pixels = si.targetSprite.texture.GetPixels((int)si.targetSprite.rect.x, (int)si.targetSprite.rect.y, (int)si.targetSprite.rect.width, (int)si.targetSprite.rect.height); texture.SetPixels(pixels); texture.Apply(); } // Handle texture source else if (si.source is Texture2D) { // Get as texture Texture2D sourceTex = si.source as Texture2D; // Check if we have as source texture if (sourceTex != null) { // Copy the source texture into the temp one texture = new Texture2D(sourceTex.width, sourceTex.height, TextureFormat.ARGB32, false); Color[] pixels = sourceTex.GetPixels(0, 0, sourceTex.width, sourceTex.height); texture.SetPixels(pixels); texture.Apply(); // Transfer the sprite data importData.border = Vector4.zero; importData.alignment = this.m_Instance.defaultPivot; importData.pivot = this.m_Instance.defaultCustomPivot; } } // Handle sprite source else if (si.source is Sprite) { // Get as sprite Sprite sourceSprite = si.source as Sprite; // Make sure we have the sprite if (sourceSprite != null) { // Copy the sprite into the temporary texture texture = new Texture2D((int)sourceSprite.rect.width, (int)sourceSprite.rect.height, TextureFormat.ARGB32, false); Color[] pixels = sourceSprite.texture.GetPixels((int)sourceSprite.rect.x, (int)sourceSprite.rect.y, (int)sourceSprite.rect.width, (int)sourceSprite.rect.height); texture.SetPixels(pixels); texture.Apply(); // Transfer the sprite data importData.border = sourceSprite.border; importData.alignment = SpriteAlignment.Custom; importData.pivot = new Vector2( (0f - sourceSprite.bounds.center.x / sourceSprite.bounds.extents.x / 2 + 0.5f), (0f - sourceSprite.bounds.center.y / sourceSprite.bounds.extents.y / 2 + 0.5f)); } } // Save the new texture into our array textures[ia] = (texture != null) ? texture : new Texture2D(1, 1); // Set the sprite import data spritesImportData[ia] = importData; // Increase the indexer ia++; } // Make the source textures assets non readable if (SPTools.GetEditorPrefBool(SPTools.Settings_DisableReadWriteEnabled)) { this.SetAssetsReadWriteEnabled(sourceTexturePaths, false); } // Clear the source textures asset paths System.Array.Clear(sourceTexturePaths, 0, sourceTexturePaths.Length); // Create a temporary texture for the packing Texture2D tempTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false); // UV coords array Rect[] uvs; // Pack the textures into the temporary if (this.m_Instance.packingMethod == SPInstance.PackingMethod.Unity) { uvs = tempTexture.PackTextures(textures, this.m_Instance.padding, this.m_Instance.maxSize); } else { uvs = UITexturePacker.PackTextures(tempTexture, textures, this.m_Instance.padding, this.m_Instance.maxSize); // Check if packing failed if (uvs == null) { Debug.LogError( "Sprite Packer texture packing failed, the textures might be exceeding the specified maximum size."); return; } } // Import and Configure the texture atlas (also disables Read/Write) SPTools.ImportAndConfigureAtlasTexture(this.m_Instance.texture, tempTexture, uvs, spritesImportData); // Clear the current sprite info list this.m_Instance.ClearSprites(); // Clear the actions list this.m_Instance.ClearActions(); // Destroy the textures from the temporary textures array for (int ib = 0; ib < textures.Length; ib++) { UnityEngine.Object.DestroyImmediate(textures[ib]); } // Destroy the temporary texture UnityEngine.Object.DestroyImmediate(tempTexture); // Convert the temporary sprite info into array SPSpriteInfo[] spriteInfoArray = spriteInfoList.ToArray(); // Clear the temporary sprite info list spriteInfoList.Clear(); // Apply the new sprite reff to the sprite info and add the sprite info to the sprites list for (int i = 0; i < spriteInfoArray.Length; i++) { SPSpriteInfo info = spriteInfoArray[i]; if (info.targetSprite == null) { info.targetSprite = SPTools.LoadSprite(this.m_Instance.texture, spritesImportData[i].name); } // Add to the instance sprite info list this.m_Instance.AddSprite(info); } // Clear the sprites import data array System.Array.Clear(spritesImportData, 0, spritesImportData.Length); // Set dirty EditorUtility.SetDirty(this.m_Instance); } else { Debug.LogError("Sprite Packer failed to make the atlas texture readable, please do it manually."); } }
public static int GetMinSize(Texture2D[] textures, UITexturePacker.FreeRectChoiceHeuristic heuristic) { int padding = 1; return GetMinAtlasSize(textures, 4, ref padding, 4, heuristic); }
private static Texture2D UpdateUIAtlas(UIAtlas atlas, List<Texture2D> textures, ref int? size, out int minSize, UITexturePacker.FreeRectChoiceHeuristic heuristic) { Debug.Log("***************** Updating atlas " + atlas.name + " - " + DateTime.Now); Rect[] texRects; Texture2D newTexture = CreateTexture(textures.ToArray(), ref size, 1, out texRects, out minSize, heuristic); List<UIAtlasMaker.SpriteEntry> sprites = UIAtlasMaker.CreateSprites(textures.Cast<Texture>().ToList()); for (int i = 0; i < sprites.Count; i++) { Rect rect = NGUIMath.ConvertToPixels(texRects[i], newTexture.width, newTexture.height, true); UIAtlasMaker.SpriteEntry se = 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); } // Replace the sprites within the atlas UIAtlasMaker.ReplaceSprites(atlas, sprites); // Release the temporary textures UIAtlasMaker.ReleaseSprites(sprites); return newTexture; }
/// <summary> /// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed. /// </summary> static bool PackTextures(Texture2D tex, List <SpriteEntry> sprites) { Texture2D[] textures = new Texture2D[sprites.Count]; Rect[] rects; #if UNITY_3_5 || UNITY_4_0 int maxSize = 4096; #else int maxSize = SystemInfo.maxTextureSize; #endif #if UNITY_ANDROID || UNITY_IPHONE maxSize = Mathf.Min(maxSize, NGUISettings.allow4096 ? 4096 : 2048); #endif if (NGUISettings.unityPacking) { for (int i = 0; i < sprites.Count; ++i) { textures[i] = sprites[i].tex; } rects = tex.PackTextures(textures, Mathf.Max(NGUISettings.atlasPadding, (NGUISettings.atlasExtendPadding << 1)), maxSize); } else { sprites.Sort(Compare); for (int i = 0; i < sprites.Count; ++i) { textures[i] = sprites[i].tex; } rects = UITexturePacker.PackTextures(tex, textures, 4, 4, Mathf.Max(NGUISettings.atlasPadding, (NGUISettings.atlasExtendPadding << 1)), maxSize); } for (int i = 0; i < sprites.Count; ++i) { Rect rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true); // Apparently Unity can take the liberty of destroying temporary textures without any warning if (textures[i] == null) { return(false); } // Make sure that we don't shrink the textures if (Mathf.RoundToInt(rect.width) != textures[i].width) { return(false); } SpriteEntry se = 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); } if (NGUISettings.atlasExtendPadding > 0) { Color32[] colors = tex.GetPixels32(); int texWidth = tex.width; int texHeight = tex.height; for (int i = 0; i < sprites.Count; ++i) { SpriteEntry se = sprites[i]; int xMin = se.x; int xMax = se.x + se.width - 1; // Y-axis is inverted int yMin = texHeight - se.y - se.height; int yMax = texHeight - se.y - 1; for (int x = xMin - NGUISettings.atlasExtendPadding; x <= xMax + NGUISettings.atlasExtendPadding; ++x) { for (int y = yMin - NGUISettings.atlasExtendPadding; y <= yMax + NGUISettings.atlasExtendPadding; ++y) { if (x < 0 || x >= texWidth || y < 0 || y >= texHeight) { // Out of tex bounds continue; } if (x >= xMin && x <= xMax && y >= yMin && y <= yMax) { // In sprite bounds continue; } int baseX = Mathf.Clamp(x, xMin, xMax); int baseY = Mathf.Clamp(y, yMin, yMax); int index = y * texWidth + x; int baseIndex = baseY * texWidth + baseX; colors[index] = colors[baseIndex]; } } } tex.SetPixels32(colors); } return(true); }
private static Texture2D CreateTexture(Texture2D[] textures, ref int? size, int padding, out Rect[] texRects, out int minAtlasSize, UITexturePacker.FreeRectChoiceHeuristic heuristic) { var result = new Texture2D(1, 1); minAtlasSize = GetMinAtlasSize(textures, size ?? 128, ref padding, size ?? 128, heuristic); Debug.Log("*************************** Min size = " + minAtlasSize + " - " + DateTime.Now) ; NGUISettings.forceSquareAtlas = true; texRects = UITexturePackerSpec.PackTexturesSpec(result, textures, minAtlasSize, minAtlasSize, padding, minAtlasSize, heuristic); Debug.Log("*************************** texture packed - " + DateTime.Now); if (size == null) { int power = (int) Math.Round(Math.Log(minAtlasSize, 2)); size = (int) Math.Pow(2, power); } if (size <= minAtlasSize) { TextureScale.Resize(result, size.Value, size.Value, InterpolationMode.HighQualityBicubic); } else { texRects = UITexturePackerSpec.PackTextures(result, textures, size.Value, size.Value, padding, size.Value); } return result; }
public static Rect[] PackTextures(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize) { if (width > maxSize && height > maxSize) { return(null); } if (width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; } UITexturePacker bp = new UITexturePacker(width, height, false); Rect[] rects = new Rect[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; Rect rect = new Rect(); for (int xPadding = 1; xPadding >= 0; --xPadding) { for (int 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; } // After having no padding if it still doesnt fit increase texture size. else if (xPadding == 0 && yPadding == 0) { return(PackTextures(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize)); } } if (rect.width != 0 && rect.height != 0) { break; } } rects[i] = rect; } texture.Resize(width, height); texture.SetPixels(new Color[width * height]); for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; Rect rect = rects[i]; Color[] colors = tex.GetPixels(); if (rect.width != tex.width + padding) { Color[] newColors = tex.GetPixels(); for (int x = 0; x < rect.width; x++) { for (int y = 0; y < rect.height; y++) { int prevIndex = ((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 - padding, (int)rect.height - padding, colors); rect.x /= width; rect.y /= height; rect.width = (rect.width - padding) / width; rect.height = (rect.height - padding) / height; rects[i] = rect; } return(rects); }
private static bool CombineSpritesHelper(string path, string dpath, string name, int padding) { string file = dpath + "/" + name + ".png"; if (System.IO.File.Exists(file)) { System.IO.File.Delete(file); } string[] paths = AssetDatabase.FindAssets("t:sprite", new string[] { path }); List <Sprite> spriteList = new List <Sprite>(); List <Texture2D> texList = new List <Texture2D>(); foreach (var o in paths) { Sprite s = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(o), typeof(Sprite)) as Sprite; if (null != s) { spriteList.Add(s); texList.Add(s.texture); } } if (texList.Count > 0) { Texture2D tex = new Texture2D(m_maxWidth, m_maxHeight, TextureFormat.ARGB32, true); Rect[] uvs = UITexturePacker.PackTextures(tex, texList.ToArray(), 4, 4, padding, m_maxWidth); if (null == uvs) { EditorUtility.DisplayDialog(path, "图集超过1024,需要分组成多张图集", "点击退出"); Object.DestroyImmediate(tex); tex = null; return(false); } else { List <SpriteMetaData> metaList = new List <SpriteMetaData>(); for (int i = 0; i < uvs.Length; ++i) { SpriteMetaData data = new SpriteMetaData(); data.alignment = (int)SpriteAlignment.Center; data.border = spriteList[i].border; data.name = spriteList[i].name; data.pivot = spriteList[i].pivot; float width = UITexturePacker.currentTexSize.x; float height = UITexturePacker.currentTexSize.y; data.rect = new Rect(uvs[i].x * width, uvs[i].y * height, uvs[i].width * width, uvs[i].height * height); //data.rect = new Rect(uvs[i].x * tex.width, uvs[i].y * tex.height, uvs[i].width * tex.width, uvs[i].height * tex.height); metaList.Add(data); } System.IO.File.WriteAllBytes(file, tex.EncodeToPNG()); AssetDatabase.ImportAsset(file, ImportAssetOptions.ForceUpdate); TextureImporter importer = AssetImporter.GetAtPath(file) as TextureImporter; importer.spritesheet = metaList.ToArray(); importer.spriteImportMode = SpriteImportMode.Multiple; importer.textureType = TextureImporterType.Sprite; importer.textureCompression = TextureImporterCompression.Uncompressed; importer.mipmapEnabled = true; importer.isReadable = true; importer.mipmapFilter = TextureImporterMipFilter.BoxFilter; AssetDatabase.ImportAsset(file); AssetDatabase.Refresh(); m_bitmapFont = new BitmapFontData(); m_bitmapFont.name = name; m_bitmapFont.charCount = metaList.Count; m_bitmapFont.height = tex.height; m_bitmapFont.width = tex.width; m_bitmapFont.size = m_fontSize; m_bitmapFont.spriteList = metaList; m_bitmapFont.Save(); m_bitmapFont.CreateFont(); } } return(true); }
bool packTextures(int maxSize, bool unityPacking) //, ref ArrayList outSprites, ref Rect[] rects) { if (packTex != null) { DestroyImmediate(packTex, true); packTex = null; } refreshSelectedCount(); if (selectedCount == 0) { Debug.LogError("Please select some sprites, that need packe"); return(false); } packSprites.Clear(); List <Texture2D> listTexs = new List <Texture2D> (); for (int i = 0; i < mSpriteList.Count; i++) { Hashtable m = mSpriteList [i] as Hashtable; if (MapEx.getBool(m, "selected")) { Hashtable d = MapEx.getMap(m, "data"); string name = MapEx.getString(d, "name"); string path = MapEx.getString(d, "path"); Texture2D tex = ECLEditorUtl.getObjectByPath(path) as Texture2D; listTexs.Add(tex); packSprites.Add(m); } } if (sortSprite != SortSprite.none) { if (sortSprite == SortSprite.SortArea) { packSprites.Sort(CompareSprite); } else { packSprites.Sort(CompareSprite2); } listTexs.Clear(); for (int i = 0; i < packSprites.Count; i++) { Hashtable d = MapEx.getMap(packSprites [i], "data"); string path = MapEx.getString(d, "path"); setTextureReadable("Assets/" + path, TextureImporterFormat.RGBA32, TextureImporterCompression.Uncompressed, true); Texture2D tex = ECLEditorUtl.getObjectByPath(path) as Texture2D; listTexs.Add(tex); } } // for (int i = 0; i < listTexs.Count; i++) { // setTextureReadable (listTexs [i] as Texture, TextureImporterFormat.RGBA32, TextureImporterCompression.Uncompressed, true); // } packTex = new Texture2D(1, 1, TextureFormat.ARGB32, false); if (unityPacking) { packRects = packTex.PackTextures(listTexs.ToArray(), NGUISettings.atlasPadding, maxSize); } else { packRects = UITexturePacker.PackTextures(packTex, listTexs.ToArray(), 4, 4, NGUISettings.atlasPadding, maxSize); } _empty = new Texture2D(packTex.width, packTex.height, TextureFormat.ARGB32, false); bool ret = true; for (int i = 0; i < listTexs.Count; ++i) { Rect rect = NGUIMath.ConvertToPixels(packRects [i], packTex.width, packTex.height, true); packRects [i] = rect; // Apparently Unity can take the liberty of destroying temporary textures without any warning if (listTexs [i] == null) { Debug.LogWarning("Apparently Unity can take the liberty of destroying temporary textures without any warning"); ret = false; break; } // Make sure that we don't shrink the textures if (Mathf.RoundToInt(rect.width) != listTexs [i].width) { Debug.LogError(rect.width + "====" + listTexs [i].width); Debug.LogWarning("Make sure that we don't shrink the textures=" + listTexs [i].name); ret = false; break; } } // for (int i = 0; i < listTexs.Count; i++) { // setTextureReadable (listTexs [i] as Texture, TextureImporterFormat.Automatic, false); // } return(ret); }
public static Rect[] PackTextures(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize) { if (width > maxSize && height > maxSize) { return(null); } if (width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; } // Force square by sizing up if (NGUISettings.forceSquareAtlas) { if (width > height) { height = width; } else if (height > width) { width = height; } } UITexturePacker bp = new UITexturePacker(width, height, false); Storage[] storage = new Storage[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; Rect rect = new Rect(); int xPadding = 1; int yPadding = 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; } // After having no padding if it still doesn't fit -- increase texture size. else if (xPadding == 0 && yPadding == 0) { return(PackTextures(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize)); } } if (rect.width != 0 && rect.height != 0) { break; } } storage[i] = new Storage(); storage[i].rect = rect; storage[i].paddingX = (xPadding != 0); storage[i].paddingY = (yPadding != 0); } texture.Resize(width, height); texture.SetPixels(new Color[width * height]); // The returned rects Rect[] rects = new Rect[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; Rect rect = storage[i].rect; int xPadding = (storage[i].paddingX ? padding : 0); int yPadding = (storage[i].paddingY ? padding : 0); Color[] colors = tex.GetPixels(); // Would be used to rotate the texture if need be. if (rect.width != tex.width + xPadding) { Color[] newColors = tex.GetPixels(); for (int x = 0; x < rect.width; x++) { for (int y = 0; y < rect.height; y++) { int prevIndex = ((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; } return(rects); }
public static Rect[] PackTextures (Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize) { if (width > maxSize && height > maxSize) return null; if (width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; } // Force square by sizing up if (NGUISettings.forceSquareAtlas) { if (width > height) height = width; else if (height > width) width = height; } UITexturePacker bp = new UITexturePacker(width, height, false); Storage[] storage = new Storage[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) continue; Rect rect = new Rect(); int xPadding = 1; int yPadding = 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; // After having no padding if it still doesn't fit -- increase texture size. else if (xPadding == 0 && yPadding == 0) { return PackTextures(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize); } } if (rect.width != 0 && rect.height != 0) break; } storage[i] = new Storage(); storage[i].rect = rect; storage[i].paddingX = (xPadding != 0); storage[i].paddingY = (yPadding != 0); } texture.Resize(width, height); texture.SetPixels(new Color[width * height]); // The returned rects Rect[] rects = new Rect[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) continue; Rect rect = storage[i].rect; int xPadding = (storage[i].paddingX ? padding : 0); int yPadding = (storage[i].paddingY ? padding : 0); Color[] colors = tex.GetPixels(); // Would be used to rotate the texture if need be. if (rect.width != tex.width + xPadding) { Color[] newColors = tex.GetPixels(); for (int x = 0; x < rect.width; x++) { for (int y = 0; y < rect.height; y++) { int prevIndex = ((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(); return rects; }
private static int GetMinAtlasSize(Texture2D[] textures, int startSize, ref int padding, int nessSize, UITexturePacker.FreeRectChoiceHeuristic heuristic) { int startDiff = startSize /2; int minDiff = 0; int size = startSize; int diff = startDiff; bool? prevResult = null; while (true) { bool curResult = CanPackTexturesInSize(textures, size, (int)Math.Ceiling(padding * ((double)size / nessSize)), heuristic); if (prevResult.HasValue && curResult != prevResult) { if (diff/2 <= minDiff) { if (!curResult) { size += diff; } padding = (int) Math.Ceiling(padding*((double) size/nessSize)); return size; } diff /= 2; } if (curResult) { size -= diff; } else { size += diff; } prevResult = curResult; } }
public static Rect[] PackTextures(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize) { if(width > maxSize && height > maxSize) return null; if(width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; } UITexturePacker bp = new UITexturePacker(width, height, false); Rect[] rects = new Rect[textures.Length]; for(int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; Rect rect = new Rect(); for (int xPadding = 1; xPadding >=0; --xPadding) { for (int 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; } // After having no padding if it still doesnt fit increase texture size. else if (xPadding == 0 && yPadding == 0) { return PackTextures(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize); } } if (rect.width != 0 && rect.height != 0) { break; } } rects[i] = rect; } texture.Resize(width, height); texture.SetPixels(new Color[width * height]); for(int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; Rect rect = rects[i]; Color[] colors = tex.GetPixels(); if(rect.width != tex.width + padding) { Color[] newColors = tex.GetPixels(); for(int x = 0; x < rect.width; x++) { for(int y = 0; y < rect.height; y++) { int prevIndex = ((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 - padding, (int)rect.height - padding, colors); rect.x /= width; rect.y /= height; rect.width = (rect.width- padding) / width ; rect.height = (rect.height - padding) / height; rects[i] = rect; } return rects; }
/// <summary> /// 以4为基础值 大小不够则乘以2扩充图片大小 /// </summary> /// <returns></returns> public static Rect[] PackTextures(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize) { if (width > maxSize && height > maxSize) { return(null); } if (width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; } UITexturePacker bp = new UITexturePacker(width, height, false); Storage[] storage = new Storage[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) { continue; } Rect rect = new Rect(); int xPadding = 1; int yPadding = 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.RectBestLongSideFit); if (rect.width != 0 && rect.height != 0) { break; } // After having no padding if it still doesn't fit -- increase texture size. else if (xPadding == 0 && yPadding == 0) { return(PackTextures(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize)); } } if (rect.width != 0 && rect.height != 0) { break; } } storage[i] = new Storage(); storage[i].rect = rect; storage[i].paddingX = (xPadding != 0); storage[i].paddingY = (yPadding != 0); } currentTexSize = new Vector2(width, height); int maxTexSize = Mathf.Max(width, height);//如果只按宽高是最优的图片大小,现在改成和Bitfont一样 导出正方形图 texture.Resize(maxTexSize, maxTexSize); texture.SetPixels(new Color[maxTexSize * maxTexSize]); // The returned rects Rect[] rects = new Rect[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) { continue; } Rect rect = storage[i].rect; int xPadding = (storage[i].paddingX ? padding : 0); int yPadding = (storage[i].paddingY ? padding : 0); Color[] colors = tex.GetPixels(); // Would be used to rotate the texture if need be. if (rect.width != tex.width + xPadding) { Color[] newColors = tex.GetPixels(); for (int x = 0; x < rect.width; x++) { for (int y = 0; y < rect.height; y++) { int prevIndex = ((int)rect.height - (y + 1)) + x * (int)tex.width; newColors[x + y * (int)rect.width] = colors[prevIndex]; } } colors = newColors; } float ry = maxTexSize - rect.y - rect.height;//原来是从下往上写入,现在修改成和bitfont导出设置一样,从上往下写入! texture.SetPixels((int)rect.x, (int)ry, (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(); return(rects); }