public static string BakeAtlas(GuiAtlas atlas, string fileName) { if (!AssetDatabase.Contains (atlas)) { return "Atlas should be saved as asset"; } if (string.IsNullOrEmpty (fileName)) { return "Sprite folder not selected"; } // cleanup. try { if (atlas.ColorTexture != null && AssetDatabase.Contains (atlas.ColorTexture)) { var t = atlas.ColorTexture; atlas.ColorTexture = null; AssetDatabase.DeleteAsset (AssetDatabase.GetAssetPath (t)); } } catch { } try { if (atlas.AlphaTexture != null && AssetDatabase.Contains (atlas.AlphaTexture)) { var t = atlas.AlphaTexture; atlas.AlphaTexture = null; AssetDatabase.DeleteAsset (AssetDatabase.GetAssetPath (t)); } } catch { } AssetDatabase.Refresh (); var sprites = new List<Texture2D> (); foreach (var spriteFileName in Directory.GetFiles (fileName, "*.png", SearchOption.TopDirectoryOnly)) { var spriteTex = new Texture2D (2, 2); spriteTex.LoadImage (File.ReadAllBytes (spriteFileName)); spriteTex.Apply (); spriteTex.name = Path.GetFileNameWithoutExtension (spriteFileName); sprites.Add (spriteTex); } var atlasTex = new Texture2D (2, 2, TextureFormat.ARGB32, false); atlasTex.hideFlags = HideFlags.HideAndDontSave; Rect[] rects; if (sprites.Count == 1) { // special case, one texture rects = new Rect[] { new Rect (0, 0, 1f, 1f) }; atlasTex.LoadImage (sprites[0].EncodeToPNG ()); atlasTex.Apply (); } else { rects = atlasTex.PackTextures (sprites.ToArray (), 2, 2048); } var tex = new Texture2D (atlasTex.width, atlasTex.height, TextureFormat.RGB24, false); tex.hideFlags = HideFlags.HideAndDontSave; var srcColors = atlasTex.GetPixels32 (); DestroyImmediate (atlasTex); atlasTex = null; var dstAlphas = new Color32[srcColors.Length]; Color32 c; for (int i = 0; i < srcColors.Length; i++) { c = srcColors[i]; dstAlphas[i] = new Color32 (c.a, c.a, c.a, 255); } tex.SetPixels32 (srcColors); var colorData = tex.EncodeToPNG (); tex.SetPixels32 (dstAlphas); var alphaData = tex.EncodeToPNG (); DestroyImmediate (tex); tex = null; try { var srcAtlasPath = AssetDatabase.GetAssetPath (atlas); EditorUtility.DisplayProgressBar ("Save and import atlas data", "Color data processing...", 1f); var atlasPath = Path.ChangeExtension (srcAtlasPath, "color.png"); File.WriteAllBytes (Path.Combine (Path.Combine (Application.dataPath, ".."), atlasPath), colorData); EditorUtility.DisplayProgressBar ("Save and import atlas data", "Alpha data processing...", 1f); var alphaAtlasPath = Path.ChangeExtension (srcAtlasPath, "alpha.png"); File.WriteAllBytes (Path.Combine (Path.Combine (Application.dataPath, ".."), alphaAtlasPath), alphaData); EditorUtility.DisplayProgressBar ("Save and import atlas data", "Import processed data...", 1f); AssetDatabase.Refresh (); atlasTex = FixAtlasImport (atlasPath); atlas.ColorTexture = atlasTex; atlas.AlphaTexture = FixAtlasImport (alphaAtlasPath); var atlasSprites = new List<GuiSpriteData> (sprites.Count); float atlasWidth = atlasTex.width; float atlasHeight = atlasTex.height; for (int i = 0, iMax = sprites.Count; i < iMax; i++) { var sprData = new GuiSpriteData (); var sprName = sprites[i].name; // slicing var match = _slicedMask.Match (sprName.ToLowerInvariant ()); if (match.Success) { sprName = sprName.Replace (match.Value, string.Empty); sprData.BorderL = int.Parse (match.Groups["left"].Value) / atlasWidth; sprData.BorderT = int.Parse (match.Groups["top"].Value) / atlasHeight; sprData.BorderR = int.Parse (match.Groups["right"].Value) / atlasWidth; sprData.BorderB = int.Parse (match.Groups["bottom"].Value) / atlasHeight; } else { sprData.BorderL = 0; sprData.BorderT = 0; sprData.BorderR = 0; sprData.BorderB = 0; } sprData.Name = sprName; sprData.CornerX = rects[i].x; sprData.CornerY = rects[i].y; sprData.CornerW = rects[i].width; sprData.CornerH = rects[i].height; atlasSprites.Add (sprData); } atlas.Sprites = atlasSprites.ToArray (); EditorUtility.SetDirty (atlas); AssetDatabase.SaveAssets (); AssetDatabase.Refresh (); atlas.ResetCache (); foreach (var panel in FindObjectsOfType<GuiPanel> ()) { panel.ResetMaterialCache (); } foreach (var vis in FindObjectsOfType<GuiWidget> ()) { vis.SetDirty (GuiDirtyType.Geometry); EditorUtility.SetDirty (vis); } } finally { EditorUtility.ClearProgressBar (); for (var i = sprites.Count - 1; i >= 0; i--) { DestroyImmediate (sprites[i]); sprites.RemoveAt (i); } } return null; }
public static string BakeAtlas(GuiAtlas atlas, string fileName) { if (!AssetDatabase.Contains(atlas)) { return("Atlas should be saved as asset"); } if (string.IsNullOrEmpty(fileName)) { return("Sprite folder not selected"); } // cleanup. try { if (atlas.ColorTexture != null && AssetDatabase.Contains(atlas.ColorTexture)) { var t = atlas.ColorTexture; atlas.ColorTexture = null; AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(t)); } } catch { } try { if (atlas.AlphaTexture != null && AssetDatabase.Contains(atlas.AlphaTexture)) { var t = atlas.AlphaTexture; atlas.AlphaTexture = null; AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(t)); } } catch { } AssetDatabase.Refresh(); var sprites = new List <Texture2D> (); foreach (var spriteFileName in Directory.GetFiles(fileName, "*.png", SearchOption.TopDirectoryOnly)) { var spriteTex = new Texture2D(2, 2); spriteTex.LoadImage(File.ReadAllBytes(spriteFileName)); spriteTex.Apply(); spriteTex.name = Path.GetFileNameWithoutExtension(spriteFileName); sprites.Add(spriteTex); } var atlasTex = new Texture2D(2, 2, TextureFormat.ARGB32, false); atlasTex.hideFlags = HideFlags.HideAndDontSave; Rect[] rects; if (sprites.Count == 1) { // special case, one texture rects = new Rect[] { new Rect(0, 0, 1f, 1f) }; atlasTex.LoadImage(sprites[0].EncodeToPNG()); atlasTex.Apply(); } else { rects = atlasTex.PackTextures(sprites.ToArray(), 2, 2048); } var tex = new Texture2D(atlasTex.width, atlasTex.height, TextureFormat.RGB24, false); tex.hideFlags = HideFlags.HideAndDontSave; var srcColors = atlasTex.GetPixels32(); DestroyImmediate(atlasTex); atlasTex = null; var dstAlphas = new Color32[srcColors.Length]; Color32 c; for (int i = 0; i < srcColors.Length; i++) { c = srcColors[i]; dstAlphas[i] = new Color32(c.a, c.a, c.a, 255); } tex.SetPixels32(srcColors); var colorData = tex.EncodeToPNG(); tex.SetPixels32(dstAlphas); var alphaData = tex.EncodeToPNG(); DestroyImmediate(tex); tex = null; try { var srcAtlasPath = AssetDatabase.GetAssetPath(atlas); EditorUtility.DisplayProgressBar("Save and import atlas data", "Color data processing...", 1f); var atlasPath = Path.ChangeExtension(srcAtlasPath, "color.png"); File.WriteAllBytes(Path.Combine(Path.Combine(Application.dataPath, ".."), atlasPath), colorData); EditorUtility.DisplayProgressBar("Save and import atlas data", "Alpha data processing...", 1f); var alphaAtlasPath = Path.ChangeExtension(srcAtlasPath, "alpha.png"); File.WriteAllBytes(Path.Combine(Path.Combine(Application.dataPath, ".."), alphaAtlasPath), alphaData); EditorUtility.DisplayProgressBar("Save and import atlas data", "Import processed data...", 1f); AssetDatabase.Refresh(); atlasTex = FixAtlasImport(atlasPath); atlas.ColorTexture = atlasTex; atlas.AlphaTexture = FixAtlasImport(alphaAtlasPath); var atlasSprites = new List <GuiSpriteData> (sprites.Count); float atlasWidth = atlasTex.width; float atlasHeight = atlasTex.height; for (int i = 0, iMax = sprites.Count; i < iMax; i++) { var sprData = new GuiSpriteData(); var sprName = sprites[i].name; // slicing var match = _slicedMask.Match(sprName.ToLowerInvariant()); if (match.Success) { sprName = sprName.Replace(match.Value, string.Empty); sprData.BorderL = int.Parse(match.Groups["left"].Value) / atlasWidth; sprData.BorderT = int.Parse(match.Groups["top"].Value) / atlasHeight; sprData.BorderR = int.Parse(match.Groups["right"].Value) / atlasWidth; sprData.BorderB = int.Parse(match.Groups["bottom"].Value) / atlasHeight; } else { sprData.BorderL = 0; sprData.BorderT = 0; sprData.BorderR = 0; sprData.BorderB = 0; } sprData.Name = sprName; sprData.CornerX = rects[i].x; sprData.CornerY = rects[i].y; sprData.CornerW = rects[i].width; sprData.CornerH = rects[i].height; atlasSprites.Add(sprData); } atlas.Sprites = atlasSprites.ToArray(); EditorUtility.SetDirty(atlas); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); atlas.ResetCache(); foreach (var panel in FindObjectsOfType <GuiPanel>()) { panel.ResetMaterialCache(); } foreach (var vis in FindObjectsOfType <GuiWidget>()) { vis.SetDirty(GuiDirtyType.Geometry); EditorUtility.SetDirty(vis); } } finally { EditorUtility.ClearProgressBar(); for (var i = sprites.Count - 1; i >= 0; i--) { DestroyImmediate(sprites[i]); sprites.RemoveAt(i); } } return(null); }
/// <summary> /// Fill simple sprite. /// </summary> /// <param name="mesh">Mesh.</param> /// <param name="width">Sprite width.</param> /// <param name="height">Sprite height.</param> /// <param name="color">Sprite color.</param> /// <param name="spriteData">Sprite data.</param> /// <param name="effect">Effect.</param> /// <param name="effectValue">Effect value.</param> /// <param name="effectColor">Effect color.</param> public static void FillSimpleSprite(Mesh mesh, int width, int height, Color color, GuiSpriteData spriteData, GuiFontEffect effect = GuiFontEffect.None, Vector2? effectValue = null, Color? effectColor = null) { if (mesh == null) { return; } PrepareBuffer (effect, effectValue, effectColor); if (spriteData != null) { var halfW = 0.5f * width; var halfH = 0.5f * height; _vRect.Set (-halfW, -halfH, width, height); _uvRect.Set (spriteData.CornerX, spriteData.CornerY, spriteData.CornerW, spriteData.CornerH); FillBuffer (ref _vRect, ref _uvRect, ref color); } GetBuffers (mesh); }
/// <summary> /// Fill sliced / tiled sprite. /// </summary> /// <param name="mesh">Mesh.</param> /// <param name="width">Sprite width.</param> /// <param name="height">Sprite height.</param> /// <param name="color">Sprite color.</param> /// <param name="sd">Sprite data.</param> /// <param name="texSize">Tex size.</param> /// <param name="isHorTiled">Is sprite tiled horizontally.</param> /// <param name="isVerTiled">Is sprite tiled vertically.</param> /// <param name="fillCenter">Is sprite center should be filled.</param> public static void FillSlicedTiledSprite( Mesh mesh, int width, int height, Color color, GuiSpriteData sd, Vector2 texSize, bool isHorTiled, bool isVerTiled, bool fillCenter) { if (mesh == null) { return; } PrepareBuffer (); if (sd != null && width != 0 && height != 0) { var leftBorderV = (int) (sd.BorderL * texSize.x); var rightBorderV = (int) (sd.BorderR * texSize.x); var topBorderV = (int) (sd.BorderT * texSize.y); var bottomBorderV = (int) (sd.BorderB * texSize.y); if ((leftBorderV + rightBorderV) <= width && (bottomBorderV + topBorderV) <= height) { var cW = sd.CenterWidth; var cH = sd.CenterHeight; var bR = sd.CornerX + sd.CornerW - sd.BorderR; var bT = sd.CornerY + sd.CornerH - sd.BorderT; var halfW = 0.5f * width; var halfH = 0.5f * height; if (width < 0) { leftBorderV = -leftBorderV; rightBorderV = -rightBorderV; } if (height < 0) { topBorderV = -topBorderV; bottomBorderV = -bottomBorderV; } int centerWidthV; int horTileCount; int centerHeightV; int verTileCount; if (isHorTiled) { centerWidthV = (int) (cW * texSize.x); if (width < 0) { centerWidthV = -centerWidthV; } horTileCount = Mathf.Max (0, Mathf.FloorToInt ((width - leftBorderV - rightBorderV) / (float) centerWidthV)); } else { centerWidthV = width - rightBorderV - leftBorderV; horTileCount = 1; } if (isVerTiled) { centerHeightV = (int) (cH * texSize.y); if (height < 0) { centerHeightV = -centerHeightV; } verTileCount = Mathf.Max (0, Mathf.FloorToInt ((height - bottomBorderV - topBorderV) / (float) centerHeightV)); } else { centerHeightV = height - topBorderV - bottomBorderV; verTileCount = 1; } // top-bottom sides if (sd.BorderT > 0 || sd.BorderB > 0) { _uvRect.Set (sd.CornerX + sd.BorderL, bT, cW, sd.BorderT); _uvRect2.Set (sd.CornerX + sd.BorderL, sd.CornerY, cW, sd.BorderB); _vRect.Set (-halfW + leftBorderV, halfH - topBorderV, centerWidthV, topBorderV); _vRect2.Set (-halfW + leftBorderV, -halfH, centerWidthV, bottomBorderV); for (var i = 0; i < horTileCount; i++) { FillBuffer (ref _vRect, ref _uvRect, ref color); FillBuffer (ref _vRect2, ref _uvRect2, ref color); _vRect.x += centerWidthV; _vRect2.x += centerWidthV; } } // left-right sides if (sd.BorderL > 0 || sd.BorderR > 0) { _uvRect.Set (sd.CornerX, sd.CornerY + sd.BorderB, sd.BorderL, cH); _uvRect2.Set (bR, sd.CornerY + sd.BorderB, sd.BorderR, cH); _vRect.Set (-halfW, -halfH + bottomBorderV, leftBorderV, centerHeightV); _vRect2.Set (halfW - rightBorderV, -halfH + bottomBorderV, rightBorderV, centerHeightV); for (var i = 0; i < verTileCount; i++) { FillBuffer (ref _vRect, ref _uvRect, ref color); FillBuffer (ref _vRect2, ref _uvRect2, ref color); _vRect.y += centerHeightV; _vRect2.y += centerHeightV; } } // center if (fillCenter) { _uvRect.Set (sd.CornerX + sd.BorderL, sd.CornerY + sd.BorderB, cW, cH); _vRect.Set (0, -halfH + bottomBorderV, centerWidthV, centerHeightV); for (var y = 0; y < verTileCount; y++) { _vRect.x = -halfW + leftBorderV; for (var x = 0; x < horTileCount; x++) { FillBuffer (ref _vRect, ref _uvRect, ref color); _vRect.x += centerWidthV; } _vRect.y += centerHeightV; } } // left-top corner if (sd.BorderL > 0 && sd.BorderT > 0) { _vRect.Set (-halfW, halfH - topBorderV, leftBorderV, topBorderV); _uvRect.Set (sd.CornerX, bT, sd.BorderL, sd.BorderT); FillBuffer (ref _vRect, ref _uvRect, ref color); } // right-top corner if (sd.BorderR > 0 && sd.BorderT > 0) { _vRect.Set (halfW - rightBorderV, halfH - topBorderV, rightBorderV, topBorderV); _uvRect.Set (bR, bT, sd.BorderR, sd.BorderT); FillBuffer (ref _vRect, ref _uvRect, ref color); } // right-bottom corner if (sd.BorderR > 0 && sd.BorderB > 0) { _vRect.Set (halfW - rightBorderV, -halfH, rightBorderV, bottomBorderV); _uvRect.Set (bR, sd.CornerY, sd.BorderR, sd.BorderB); FillBuffer (ref _vRect, ref _uvRect, ref color); } // left-bottom corner if (sd.BorderL > 0 && sd.BorderB > 0) { _vRect.Set (-halfW, -halfH, leftBorderV, bottomBorderV); _uvRect.Set (sd.CornerX, sd.CornerY, sd.BorderL, sd.BorderB); FillBuffer (ref _vRect, ref _uvRect, ref color); } } } GetBuffers (mesh); }
/// <summary> /// Fill round-filled sprite. /// </summary> /// <param name="mesh">Mesh.</param> /// <param name="width">Sprite width.</param> /// <param name="height">Sprite height.</param> /// <param name="fillValue">Normalized progress of round-filling.</param> /// <param name="color">Sprite color.</param> /// <param name="spriteData">Sprite data.</param> /// <param name="effect">Effect.</param> /// <param name="effectValue">Effect value.</param> /// <param name="effectColor">Effect color.</param> public static void FillRoundFilledSprite( Mesh mesh, int width, int height, float fillValue, Color color, GuiSpriteData spriteData, GuiFontEffect effect = GuiFontEffect.None, Vector2? effectValue = null, Color? effectColor = null) { if (mesh == null) { return; } PrepareBuffer (effect, effectValue, effectColor); if (spriteData != null && fillValue > 0f) { var halfW = 0.5f * width; var halfH = 0.5f * height; _vRect.Set (-halfW, -halfH, width, height); _uvRect.Set (spriteData.CornerX, spriteData.CornerY, spriteData.CornerW, spriteData.CornerH); var uvHalfW = spriteData.CornerW * 0.5f; var uvHalfH = spriteData.CornerH * 0.5f; int i; for (i = 0; i < 4; i++) { _uvRect.Set ( RoundFilledUV[i].x * uvHalfW + spriteData.CornerX, RoundFilledUV[i].y * uvHalfH + spriteData.CornerY, uvHalfW, uvHalfH); _vRect.Set (RoundFilledV[i].x * halfW, RoundFilledV[i].y * halfH, halfW, halfH); if (fillValue < (i + 1) * 0.25f) { break; } FillBuffer (ref _vRect, ref _uvRect, ref color); } if (i < 4) { fillValue = (fillValue - i * 0.25f) * 8f; var needFlip = (i & 1) == 0; var uv0 = new Vector2 (_uvRect.xMin, _uvRect.yMin); var uv1 = new Vector2 (_uvRect.xMin, _uvRect.yMax); var uv2 = new Vector2 (_uvRect.xMax, _uvRect.yMax); var uv3 = new Vector2 (_uvRect.xMax, _uvRect.yMin); var v0 = new Vector3 (_vRect.xMin, _vRect.yMin, 0f); var v1 = new Vector3 (_vRect.xMin, _vRect.yMax, 0f); var v2 = new Vector3 (_vRect.xMax, _vRect.yMax, 0f); var v3 = new Vector3 (_vRect.xMax, _vRect.yMin, 0f); if (needFlip) { var t = uv0.y; uv0.y = uv1.y; uv1.y = t; t = uv2.y; uv2.y = uv3.y; uv3.y = t; t = v0.y; v0.y = v1.y; v1.y = t; t = v2.y; v2.y = v3.y; v3.y = t; } var fvW = _vRect.width * fillValue; var fvH = _vRect.height * fillValue; var fuvW = _uvRect.width * fillValue; var fuvH = _uvRect.height * fillValue; if (fillValue >= 1f) { // more than 45 degrees. fvW -= _vRect.width; fvH -= _vRect.height; fuvW -= _uvRect.width; fuvH -= _uvRect.height; switch (i) { case 0: v1.y = _vRect.yMax - fvH; uv1.y = _uvRect.yMax - fuvH; break; case 1: v3.x = _vRect.xMin + fvW; uv3.x = _uvRect.xMin + fuvW; break; case 2: v3.y = _vRect.yMin + fvH; uv3.y = _uvRect.yMin + fuvH; break; case 3: v1.x = _vRect.xMax - fvW; uv1.x = _uvRect.xMax - fuvW; break; } } else { // less than 45 degrees switch (i) { case 0: v0.x = _vRect.xMax - fvW; uv0.x = _uvRect.xMax - fuvW; uv1 = uv0; v1 = v0; break; case 1: v0.y = _vRect.yMax - fvH; uv0.y = _uvRect.yMax - fuvH; uv3 = uv0; v3 = v0; break; case 2: v2.x = _vRect.xMin + fvW; uv2.x = _uvRect.xMin + fuvW; uv3 = uv2; v3 = v2; break; case 3: v2.y = _vRect.yMin + fvH; uv2.y = _uvRect.yMin + fuvH; uv1 = uv2; v1 = v2; break; } } FillBuffer (ref v0, ref v1, ref v2, ref v3, ref uv0, ref uv1, ref uv2, ref uv3, ref color); } } GetBuffers (mesh); }