private void AddSpriteSheet(IExportContainer container, TextureImporter importer) { if (importer.SpriteMode == SpriteImportMode.Single) { var kvp = m_sprites.First(); SpriteMetaData smeta = kvp.Key.GenerateSpriteMetaData(container, kvp.Value); importer.SpriteSheet = new SpriteSheetMetaData(ref smeta); } else { List <SpriteMetaData> metadata = new List <SpriteMetaData>(m_sprites.Count); foreach (var kvp in m_sprites) { SpriteMetaData smeta = kvp.Key.GenerateSpriteMetaData(container, kvp.Value); if (SpriteMetaData.HasInternalID(container.ExportVersion)) { smeta.InternalID = ObjectUtils.GenerateInternalID(); } metadata.Add(smeta); } importer.SpriteSheet.Sprites = metadata.ToArray(); } }
static void SliceSprites() { Texture2D[] textures = new Texture2D[totalSprites]; for (int z = 0; z < totalSprites; z++) { // path is Assets/Resources/Sprites/Sprite (1).png textures[z] = Resources.Load <Texture2D>("Sprites/Sprite (" + (z + 1) + ")"); string path = AssetDatabase.GetAssetPath(textures[z]); TextureImporter ti = AssetImporter.GetAtPath(path) as TextureImporter; ti.isReadable = true; ti.spriteImportMode = SpriteImportMode.Multiple; List <SpriteMetaData> newData = new List <SpriteMetaData>(); int SliceWidth = 12; int SliceHeight = 12; for (int i = 0; i < textures[z].width; i += SliceWidth) { for (int j = textures[z].height; j > 0; j -= SliceHeight) { SpriteMetaData smd = new SpriteMetaData(); smd.pivot = new Vector2(0.5f, 0.5f); smd.alignment = 9; smd.name = (textures[z].height - j) / SliceHeight + ", " + i / SliceWidth; smd.rect = new Rect(i, j - SliceHeight, SliceWidth, SliceHeight); newData.Add(smd); } } ti.spritesheet = newData.ToArray(); AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); } Debug.Log("Done Slicing!"); }
public void Save() { string filePath = UGUISpritePacker.m_currentPath + "/" + name + ".txt"; StringBuilder stringBuilder = new StringBuilder(); string line1 = string.Format(firstLine, face, size); string line2 = string.Format(secondLine, size, width, height); string line3 = string.Format(thirdLine, name); string line4 = string.Format(fourthLine, charCount); stringBuilder.AppendLine(line1); stringBuilder.AppendLine(line2); stringBuilder.AppendLine(line3); stringBuilder.AppendLine(line4); for (int i = 0; i < charCount; i++) { SpriteMetaData smd = spriteList[i]; string temp = string.Format(commonLine, StringToASCII(smd.name), smd.rect.x, smd.rect.y, smd.rect.width, smd.rect.height, 0, 0, smd.rect.width); stringBuilder.AppendLine(temp); } System.IO.StreamWriter writer = null; if (!System.IO.File.Exists(filePath)) { writer = System.IO.File.CreateText(filePath); } else { writer = new System.IO.StreamWriter(filePath, false, System.Text.Encoding.UTF8); } writer.Write(stringBuilder.ToString()); writer.Close(); #if UNITY_EDITOR UnityEditor.AssetDatabase.SaveAssets(); UnityEditor.AssetDatabase.Refresh(); #endif }
private static void CreateMultipleModeSpriteImporter(string path, Rect[] rects, int width, int height, List <string> nameList) { //Debug.LogError(path); TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter; importer.textureType = TextureImporterType.Sprite; importer.spriteImportMode = SpriteImportMode.Multiple; SpriteMetaData[] metaDatas = new SpriteMetaData[rects.Length]; for (int i = 0; i < metaDatas.Length; i++) { SpriteMetaData metaData = new SpriteMetaData(); metaData.name = nameList[i]; // texturesName[i].Replace(TEMP_TOKEN, ""); Rect rect = rects[i]; //Debug.Log(string.Format("{0} {1} {2} {3}", rect.xMin * width, rect.yMin * height, // rect.width * width, rect.height)); metaData.rect = new Rect(rect.xMin * width, rect.yMin * height, rect.width * width, rect.height * height); metaData.pivot = new Vector2(0.5f, 0.5f); metaDatas[i] = metaData; } importer.spritesheet = metaDatas; importer.maxTextureSize = 2048; importer.filterMode = FilterMode.Bilinear; importer.mipmapEnabled = false; importer.isReadable = false; TextureImporterFormat format = TextureImporterFormat.AutomaticCompressed; //if (GetFolderQualitySetting(folderPath) == QUALITY_TURE_COLOR) { //format = TextureImporterFormat.AutomaticTruecolor; } importer.textureFormat = format; TextureImporterSettings setting = new TextureImporterSettings(); importer.ReadTextureSettings(setting); importer.SetTextureSettings(setting); }
/// <summary> /// 写信息到SpritesSheet里 /// </summary> /// <param name="elemList"></param> /// <param name="sheetPath"></param> /// <param name="borders"></param> static void WriteMeta(XmlNodeList elemList, string sheetPath, Dictionary <string, Vector4> borders) { Texture2D texture = AssetDatabase.LoadAssetAtPath <Texture2D>(sheetPath); string impPath = AssetDatabase.GetAssetPath(texture); TextureImporter asetImp = TextureImporter.GetAtPath(impPath) as TextureImporter; for (int i = 0; i < asetImp.spritesheet.Length; i++) { //如果这张图集已经拉好了9宫格,需要先保存起来 if (asetImp.spritesheet[i].border.x != 0 || asetImp.spritesheet[i].border.y != 0 || asetImp.spritesheet[i].border.z != 0 || asetImp.spritesheet[i].border.w != 0) { borders.Add(asetImp.spritesheet[i].name, asetImp.spritesheet[i].border); } } SpriteMetaData[] metaData = new SpriteMetaData[elemList.Count]; for (int i = 0, size = elemList.Count; i < size; i++) { XmlElement node = (XmlElement)elemList.Item(i); Rect rect = new Rect(); rect.x = int.Parse(node.GetAttribute("x")); rect.y = texture.height - int.Parse(node.GetAttribute("y")) - int.Parse(node.GetAttribute("height")); rect.width = int.Parse(node.GetAttribute("width")); rect.height = int.Parse(node.GetAttribute("height")); metaData[i].rect = rect; metaData[i].pivot = new Vector2(0.5f, 0.5f); metaData[i].name = node.GetAttribute("name"); if (borders.ContainsKey(metaData[i].name)) { metaData[i].border = borders[metaData[i].name]; } } asetImp.spritesheet = metaData; asetImp.textureType = TextureImporterType.Sprite; asetImp.spriteImportMode = SpriteImportMode.Multiple; asetImp.mipmapEnabled = false; asetImp.SaveAndReimport(); }
public static List <SpriteMetaData> CalculateSpriteMetaData(TextureImporter spriteImporter, int subSpritesCount, SpriteAlignment spriteAlignment, Vector2 customOffset, int pixelSizeWidth, int pixelSizeHeight) { bool failed = false; List <SpriteMetaData> metaDataList = new List <SpriteMetaData>(); // Calculate SpriteMetaData (sliced SpriteSheet) for (int i = 0; i < subSpritesCount; i++) { try { SpriteMetaData spriteMetaData = new SpriteMetaData { alignment = (int)spriteAlignment, border = new Vector4(), name = System.IO.Path.GetFileNameWithoutExtension(spriteImporter.assetPath) + "_" + i, pivot = GetPivotValue(spriteAlignment, customOffset), rect = new Rect(i * pixelSizeWidth, 0, pixelSizeWidth, pixelSizeHeight) }; metaDataList.Add(spriteMetaData); } catch (Exception exception) { failed = true; Debug.LogException(exception); } } if (failed) { return(null); } else { return(metaDataList); } }
private void PreprocessSpriteSheet(List <Sprite> sprites, string path) { TextureImporter ti = (TextureImporter)TextureImporter.GetAtPath(path); TextureImporterSettings importerSettings = new TextureImporterSettings(); bool isSpriteUnsliced = sprites.Count == 1 || importerSettings.spriteMode == (int)SpriteImportMode.Single; bool isSpriteSliceable = sprites[0].texture.width > sprites[0].texture.height && sprites[0].texture.width % sprites[0].texture.height == 0; if (isSpriteUnsliced && isSpriteSliceable) { //set import metadata ti.ReadTextureSettings(importerSettings); importerSettings.spritePixelsPerUnit = 128; importerSettings.filterMode = FilterMode.Point; importerSettings.mipmapEnabled = false; importerSettings.alphaIsTransparency = true; importerSettings.spriteMode = (int)SpriteImportMode.Multiple; ti.SetTextureSettings(importerSettings); //slice the sprite int frameCount = (int)Mathf.Floor(sprites[0].texture.width / sprites[0].texture.height); SpriteMetaData[] frames = new SpriteMetaData[frameCount]; float cellWidth = sprites[0].texture.height; for (int i = 0; i < frameCount; i++) { frames[i] = new SpriteMetaData(); frames[i].alignment = 0; frames[i].name = sprites[0].name + "_" + i.ToString(); frames[i].rect = new Rect(i * cellWidth, 0f, cellWidth, cellWidth); frames[i].border = new Vector4(cellWidth, cellWidth, cellWidth, cellWidth); frames[i].pivot = new Vector2(cellWidth / 2, cellWidth / 2); } ti.spritesheet = frames; AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); } }
public SpriteMetaData BuildBasicSprite(float scale, Color32 defaultColor) { SpriteMetaData smd = new SpriteMetaData(); Rect rect; if (!rotated) { rect = this.frame; } else { rect = new Rect(frame.x, frame.y, frame.height, frame.width); } /* Look if frame is outside from texture */ if ((frame.x + frame.width) > atlasSize.x || (frame.y + frame.height) > atlasSize.y || (frame.x < 0 || frame.y < 0)) { Debug.Log(this.name + " is outside from texture! Sprite is ignored!"); smd.name = "IGNORE_SPRITE"; return(smd); } //calculate Height /* Example: Texture: 1000 Width x 500 height * Sprite.Recht(0,0,100,100) --> Sprite is on the bottom left */ rect.y = atlasSize.y - frame.y - rect.height; smd.rect = rect; smd.alignment = (int)SpriteAlignment.Center; smd.name = name; smd.pivot = new Vector2(frame.width / 2, frame.height / 2); return(smd); }
public SpriteMetaData[] GetSpriteSheet(SpriteAlignment spriteAlignment, Vector2 custom) { SpriteMetaData[] metaData = new SpriteMetaData[frames.Count]; for (int i = 0; i < frames.Count; i++) { ImportedAnimationFrame spriteInfo = frames[i]; SpriteMetaData spriteMetaData = new SpriteMetaData(); // sprite alignment if (spriteInfo.trimmed) { var pivotBeforeTrim = GetPivotValue(spriteAlignment, custom); var originAfterTrim = spriteInfo.spriteSourceRect.position / spriteInfo.sourceSize; var ratio = new Vector2(spriteInfo.sourceSize.x / spriteInfo.rect.size.x, spriteInfo.sourceSize.y / spriteInfo.rect.size.y); spriteMetaData.alignment = (int)SpriteAlignment.Custom; spriteMetaData.pivot = ratio * (pivotBeforeTrim - originAfterTrim); } else { spriteMetaData.alignment = (int)spriteAlignment; if (spriteAlignment == SpriteAlignment.Custom) { spriteMetaData.pivot.x = custom.x; spriteMetaData.pivot.y = custom.y; } } spriteMetaData.name = spriteInfo.name; spriteMetaData.rect = new Rect(spriteInfo.rect.position, spriteInfo.rect.size); metaData[i] = spriteMetaData; } return(metaData); }
void ImportTexture() { string _texPath = AssetDatabase.GetAssetPath(texFile); TextureImporter ti = AssetImporter.GetAtPath(_texPath) as TextureImporter; // 生成Sprite List <SpriteMetaData> sps = new List <SpriteMetaData>(); foreach (Frame f in frames.frames) { SpriteMetaData md = new SpriteMetaData(); int width = f.rotated ? f.frame.h : f.frame.w; int height = f.rotated ? f.frame.w : f.frame.h; int x = f.frame.x; // TexturePacker以左上为原点,Unity以左下为原点 int y = frames.meta.size.h - height - f.frame.y; md.rect = new Rect(x, y, width, height); md.pivot = md.rect.center; md.name = System.IO.Path.ChangeExtension(f.filename, null); sps.Add(md); } ti.textureType = TextureImporterType.Sprite; ti.spriteImportMode = SpriteImportMode.Multiple; ti.spritePixelsPerUnit = 1; ti.filterMode = FilterMode.Point; ti.textureCompression = TextureImporterCompression.Uncompressed; ti.spritesheet = sps.ToArray(); AssetDatabase.ImportAsset(_texPath, ImportAssetOptions.ForceUncompressedImport); }
// ================================================================================ // Sprite Data // -------------------------------------------------------------------------------- public SpriteMetaData[] GetSpriteSheet( SpriteAlignment spriteAlignment, CustomAlignmentType customAlignmentType, float customX, float customY ) { SpriteMetaData[] metaData = new SpriteMetaData[frames.Count]; for (int i = 0; i < frames.Count; i++) { ImportedAnimationFrame spriteInfo = frames[i]; SpriteMetaData spriteMetaData = new SpriteMetaData(); // sprite alignment spriteMetaData.alignment = (int)spriteAlignment; if (spriteAlignment == SpriteAlignment.Custom) { spriteMetaData.pivot.x = customX; spriteMetaData.pivot.y = customY; if (customAlignmentType == CustomAlignmentType.Pixels) { spriteMetaData.pivot.x /= spriteInfo.width; spriteMetaData.pivot.y /= spriteInfo.height; } } spriteMetaData.name = spriteInfo.name; spriteMetaData.rect = new Rect(spriteInfo.x, spriteInfo.y, spriteInfo.width, spriteInfo.height); metaData[i] = spriteMetaData; } return(metaData); }
static List <SpriteMetaData> ParseSprites(XElement xml, int texH) { List <SpriteMetaData> data = new List <SpriteMetaData> (); IEnumerable <XElement> elements = xml.Elements("SubTexture"); foreach (XElement e in elements) { Rect r = new Rect(); r.width = (float)e.Attribute("width"); r.height = (float)e.Attribute("height"); r.x = (float)e.Attribute("x"); r.y = (float)texH - (float)e.Attribute("y") - r.height; SpriteMetaData sprite = new SpriteMetaData(); sprite.rect = r; sprite.name = e.Attribute("name").Value; sprite.name = Path.GetFileNameWithoutExtension(sprite.name); data.Add(sprite); } return(data); }
/// <summary> /// 在打图集之前,要先把原来的图集的九宫信息存储 /// 以防丢失 /// </summary> public int SaveBorders() { string __sheetFullPath = _sheetUnityPath + ".png"; if (!File.Exists(__sheetFullPath)) { return(0); } TextureImporter asetImp = TextureImporter.GetAtPath(__sheetFullPath) as TextureImporter; if (asetImp == null) { EditorUtility.DisplayDialog("错误", "保存九宫失败,将终止打图集操作,请勿清空控制台log。联系 古光仁!!", "确定"); return(-1); } SpriteMetaData[] __metaData = asetImp.spritesheet; borderMap = new Dictionary <string, Vector4>(); for (int i = 0; i < __metaData.Length; i++) { SpriteMetaData __data = __metaData[i]; borderMap.Add(__data.name, __data.border); } return(1); }
// ================================================================================ // Sprite Data // -------------------------------------------------------------------------------- public SpriteMetaData[] GetSpriteSheet(SpriteAlignment spriteAlignment, Vector2 pivotPoint) { SpriteMetaData[] metaData = new SpriteMetaData[Frames.Count]; for (int i = 0; i < Frames.Count; i++) { ImportedAnimationFrame spriteInfo = Frames[i]; SpriteMetaData spriteMetaData = new SpriteMetaData(); // Sprite alignment spriteMetaData.alignment = (int)spriteAlignment; if (spriteAlignment == SpriteAlignment.Custom) { spriteMetaData.pivot = pivotPoint; } spriteMetaData.name = spriteInfo.Name; spriteMetaData.rect = new Rect(spriteInfo.X, spriteInfo.Y, spriteInfo.Width, spriteInfo.Height); metaData[i] = spriteMetaData; } return(metaData); }
static void ProcessForPivot() { TextAsset txt = (TextAsset)Selection.activeObject; string rootPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(txt)); string textureName = GetTextureName(txt.text); string texturePath = rootPath + "/" + textureName; TextureImporter textureImporter = AssetImporter.GetAtPath(texturePath) as TextureImporter; if (textureImporter.spriteImportMode.Equals(SpriteImportMode.Multiple)) { List <SpriteMetaData> sprites = new List <SpriteMetaData>(textureImporter.spritesheet); Dictionary <string, SpriteAlignment> pivotTable = GetPivotsDict(txt.text); for (int i = 0; i < sprites.Count; i++) { SpriteMetaData sprite = sprites[i]; string spriteName = sprite.name; if (pivotTable.ContainsKey(spriteName)) { sprite.alignment = (int)pivotTable[spriteName]; sprites[i] = sprite; } } textureImporter.spritesheet = sprites.ToArray(); textureImporter.textureType = TextureImporterType.Sprite; textureImporter.spriteImportMode = SpriteImportMode.Multiple; AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate); } else { Debug.LogError("Texture Pivot Parser: the corresponding sprite's Sprite Mode is not Multiple"); } }
static void SetPivots() { UnityEngine.Object[] textures = GetSelectedTextures(); Selection.objects = GetSelectedTextures(); foreach (Texture2D texture in textures) { string path = AssetDatabase.GetAssetPath(texture); TextureImporter ti = AssetImporter.GetAtPath(path) as TextureImporter; List <SpriteMetaData> newData = new List <SpriteMetaData>(); for (int i = 0; i < ti.spritesheet.Length; i++) { SpriteMetaData d = ti.spritesheet[i]; d.pivot = new Vector2(0.0f, d.rect.height); newData.Add(d); } ti.spritesheet = newData.ToArray(); AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); } }
static SpriteMetaData[] CreateSpriteSheetForTextureBogdan(Texture2D texture, SpriteSlicingOptions slicingOptions) { Rect[] gridRects = InternalSpriteUtility.GenerateGridSpriteRectangles(texture, Vector2.zero, slicingOptions.CellSize, Vector2.zero); string path = AssetDatabase.GetAssetPath(texture); var importer = AssetImporter.GetAtPath(path) as TextureImporter; var spriteSheet = importer.spritesheet ?? new SpriteMetaData[gridRects.Length]; // Add new sprite meta data to the end for all the newly parsed grid rects? if (importer.spritesheet != null) { spriteSheet = spriteSheet.Concat(new SpriteMetaData[Mathf.Max(0, gridRects.Length - importer.spritesheet.Length)]).ToArray(); } for (var i = 0; i < spriteSheet.Length; i++) { bool sliceExists = importer.spritesheet != null && i < importer.spritesheet.Length; bool changePivot = !sliceExists || slicingOptions.OverridePivot; spriteSheet[i] = new SpriteMetaData { alignment = changePivot ? (int)slicingOptions.Pivot: spriteSheet[i].alignment, pivot = changePivot ? slicingOptions.CustomPivot : spriteSheet[i].pivot, name = sliceExists ? spriteSheet[i].name : texture.name + "_" + i, rect = gridRects[i] }; } if (slicingOptions.Frames > 0) { spriteSheet = spriteSheet.Take((int)slicingOptions.Frames).ToArray(); } return(spriteSheet); }
void PackHorizontalSprite(int tilePerRow, int tileSize, Color[] colors, int id, int subId, int tileWidth, ref int tileX, ref int tileY, ref int spriteInd, ref SpriteMetaData[] sprites, ref Texture2D texture) { if (tileX + tileWidth >= tilePerRow) { tileX = 0; tileY += 1; } texture.SetPixels( tileX * tileSize, tileY * tileSize, tileSize * tileWidth, tileSize, colors ); sprites [spriteInd] = new SpriteMetaData { name = "sprite_" + id + "_" + subId + "_" + tileWidth, rect = new Rect(tileX * tileSize, tileY * tileSize, tileSize * tileWidth, tileSize) }; spriteInd += 1; tileX += tileWidth; }
private void CreateAtlas() { var textures = new List <Texture2D>(); var spriteRenderers = new List <SpriteRenderer>(); LayerList = new List <string>(); int zOrder = 0; var root = new GameObject(fileName); foreach (var layer in psd.Layers) { if (layer.Visible && layer.Rect.width > 0 && layer.Rect.height > 0) { if (LayerList.IndexOf(layer.Name.Split('|').Last()) == -1) { LayerList.Add(layer.Name.Split('|').Last()); var tex = CreateTexture(layer); textures.Add(tex); var go = new GameObject(layer.Name); var sr = go.AddComponent <SpriteRenderer>(); go.transform.localPosition = new Vector3((layer.Rect.width / 2 + layer.Rect.x) / pixelsToUnitSize, (-layer.Rect.height / 2 - layer.Rect.y) / pixelsToUnitSize, 0); spriteRenderers.Add(sr); sr.sortingOrder = zOrder++; go.transform.parent = root.transform; } } } Rect[] rects; var atlas = new Texture2D(atlassize, atlassize); var textureArray = textures.ToArray(); rects = atlas.PackTextures(textureArray, 2, atlassize); var Sprites = new List <SpriteMetaData>(); for (int i = 0; i < rects.Length; i++) { var smd = new SpriteMetaData(); smd.name = spriteRenderers[i].name.Split('|').Last(); smd.rect = new Rect(rects[i].xMin * atlas.width, rects[i].yMin * atlas.height, rects[i].width * atlas.width, rects[i].height * atlas.height); smd.pivot = new Vector2(0.5f, 0.5f); smd.alignment = (int)SpriteAlignment.Center; Sprites.Add(smd); } // Need to load the image first var assetPath = AssetDatabase.GetAssetPath(image); var path = Path.Combine(Path.GetDirectoryName(assetPath), Path.GetFileNameWithoutExtension(assetPath) + "_atlas" + ".png"); var buf = atlas.EncodeToPNG(); File.WriteAllBytes(path, buf); AssetDatabase.Refresh(); // Get our texture that we loaded atlas = (Texture2D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)); var textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; // Make sure the size is the same as our atlas then create the spritesheet textureImporter.maxTextureSize = atlassize; textureImporter.spritesheet = Sprites.ToArray(); textureImporter.textureType = TextureImporterType.Sprite; textureImporter.spriteImportMode = SpriteImportMode.Multiple; textureImporter.spritePivot = new Vector2(0.5f, 0.5f); textureImporter.spritePixelsPerUnit = pixelsToUnitSize; textureImporter.textureFormat = TextureImporterFormat.AutomaticTruecolor; AssetDatabase.ImportAsset(path, ImportAssetOptions.Default); foreach (Texture2D tex in textureArray) { DestroyImmediate(tex); } AssetDatabase.Refresh(); DestroyImmediate(root); var atlases = AssetDatabase.LoadAllAssetsAtPath(path).Select(x => x as Sprite).Where(x => x != null).ToArray(); CreateGUI(atlases); }
/// <summary> /// Imports and configures atlas texture. /// </summary> /// <returns><c>true</c>, if import and configure atlas texture was successful, <c>false</c> otherwise.</returns> /// <param name="targetTexture">Target texture.</param> /// <param name="sourceTexture">Source texture.</param> /// <param name="uvs">Uvs.</param> /// <param name="names">Names.</param> /// <param name="defaultPivot">Default pivot.</param> /// <param name="defaultCustomPivot">Default custom pivot.</param> public static bool ImportAndConfigureAtlasTexture(Texture2D targetTexture, Texture2D sourceTexture, Rect[] uvs, SPSpriteImportData[] spritesImportData) { // Get the asset path string assetPath = SPTools.GetAssetPath(targetTexture); if (string.IsNullOrEmpty(assetPath)) { Debug.LogError("Sprite Packer failed to Import and Configure the atlas texture, reason: Could not resolve asset path."); return(false); } // Clear the read-only flag in texture file attributes if (!SPTools.RemoveReadOnlyFlag(assetPath)) { Debug.LogError("Sprite Packer failed to Import and Configure the atlas texture, reason: Could not remove the readonly flag from the asset."); return(false); } // Write the source texture data to the asset byte[] bytes = sourceTexture.EncodeToPNG(); System.IO.File.WriteAllBytes(assetPath, bytes); bytes = null; // Get the asset texture importer TextureImporter texImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter; if (texImporter == null) { Debug.LogError("Sprite Packer failed to Import and Configure the atlas texture, reason: Could not get the texture importer for the asset."); return(false); } // Get the asset texture importer settings TextureImporterSettings texImporterSettings = new TextureImporterSettings(); // Apply sprite type texImporter.textureType = TextureImporterType.Sprite; texImporter.spriteImportMode = SpriteImportMode.Multiple; // Configure the spritesheet meta data SpriteMetaData[] spritesheetMeta = new SpriteMetaData[uvs.Length]; for (int i = 0; i < uvs.Length; i++) { if (SPTools.HasSpritesheetMeta(texImporter.spritesheet, spritesImportData[i].name)) { SpriteMetaData currentMeta = SPTools.GetSpritesheetMeta(texImporter.spritesheet, spritesImportData[i].name); Rect currentRect = uvs[i]; currentRect.x *= sourceTexture.width; currentRect.width *= sourceTexture.width; currentRect.y *= sourceTexture.height; currentRect.height *= sourceTexture.height; currentMeta.rect = currentRect; spritesheetMeta[i] = currentMeta; } else { SpriteMetaData currentMeta = new SpriteMetaData(); Rect currentRect = uvs[i]; currentRect.x *= sourceTexture.width; currentRect.width *= sourceTexture.width; currentRect.y *= sourceTexture.height; currentRect.height *= sourceTexture.height; currentMeta.rect = currentRect; currentMeta.name = spritesImportData[i].name; currentMeta.alignment = (int)spritesImportData[i].alignment; currentMeta.pivot = spritesImportData[i].pivot; currentMeta.border = spritesImportData[i].border; spritesheetMeta[i] = currentMeta; } } texImporter.spritesheet = spritesheetMeta; // Read the texture importer settings texImporter.ReadTextureSettings(texImporterSettings); // Disable Read/Write texImporterSettings.readable = false; // Re-set the texture importer settings texImporter.SetTextureSettings(texImporterSettings); // Save and Reimport the asset AssetDatabase.SaveAssets(); SPTools.DoAssetReimport(assetPath, ImportAssetOptions.ForceUpdate | ImportAssetOptions.ForceSynchronousImport); // Return success return(true); }
private void PerformSlice() { XmlDocument document = new XmlDocument(); document.LoadXml(xmlAsset.text); XmlElement root = document.DocumentElement; if (root.Name == "TextureAtlas") { bool failed = false; Texture2D texture = AssetDatabase.LoadMainAssetAtPath(importer.assetPath) as Texture2D; int textureHeight = texture.height; List <SpriteMetaData> metaDataList = new List <SpriteMetaData>(); foreach (XmlNode childNode in root.ChildNodes) { if (childNode.Name == "SubTexture") { try { int width = Convert.ToInt32(childNode.Attributes["width"].Value); int height = Convert.ToInt32(childNode.Attributes["height"].Value); int x = Convert.ToInt32(childNode.Attributes["x"].Value); int y = textureHeight - (height + Convert.ToInt32(childNode.Attributes["y"].Value)); SpriteMetaData spriteMetaData = new SpriteMetaData { alignment = (int)spriteAlignment, border = new Vector4(), name = childNode.Attributes["name"].Value, pivot = GetPivotValue(spriteAlignment, customOffset), rect = new Rect(x, y, width, height) }; metaDataList.Add(spriteMetaData); } catch (Exception exception) { failed = true; Debug.LogException(exception); } } else { Debug.LogError("Child nodes should be named 'SubTexture' !"); failed = true; } } if (!failed) { importer.spriteImportMode = SpriteImportMode.Multiple; importer.spritesheet = metaDataList.ToArray(); EditorUtility.SetDirty(importer); try { AssetDatabase.StartAssetEditing(); AssetDatabase.ImportAsset(importer.assetPath); } finally { AssetDatabase.StopAssetEditing(); Close(); } } } else { Debug.LogError("XML needs to have a 'TextureAtlas' root node!"); } }
/// <summary> /// Generate the selected water tile /// </summary> /// <param name="path"></param> /// <param name="sub_blocks_water"></param> /// <param name="sub_blocks_water_to_import"></param> /// <param name="mini_tile_w"></param> /// <param name="mini_tile_h"></param> /// <param name="wBlock"></param> /// <param name="hBlock"></param> /// <param name="generate_sprite_sheet_image"></param> public virtual void Generate_Water_Tiles(string path, List <Texture2D> sub_blocks_water, List <bool> sub_blocks_water_to_import, int mini_tile_w, int mini_tile_h, int wBlock, int hBlock, bool generate_sprite_sheet_image) { //create the final directory for the auto tile if (!Directory.Exists(Tiles_Utility.Auto_Tile_Folder_Path)) { Directory.CreateDirectory(Tiles_Utility.Auto_Tile_Folder_Path); } //create the final directory for the generated Images if (!Directory.Exists(Tiles_Utility.final_image_folder_path)) { Directory.CreateDirectory(Tiles_Utility.final_image_folder_path); } //create the folder for that specific file image string fileName = Path.GetFileNameWithoutExtension(path); string loaded_file_image_path = string.Format(@"{0}/_{1}", Tiles_Utility.final_image_folder_path, fileName); //ex rtp_import\Outside_A2\single_block_folder\final_tile\Image if (!Directory.Exists(loaded_file_image_path)) { Directory.CreateDirectory(loaded_file_image_path); } List <string> images_path = new List <string>();//list of the folder of the imported tiles Dictionary <byte, int> rule_tiles = new Dictionary <byte, int>(); //foreach sub pieces in the image. If it's an animated auto tile 3 consecutive sub blocks are 3 frame of the animation for (int sub_block_count = 0; sub_block_count < sub_blocks_water_to_import.Count; sub_block_count++) { //If the current sub is not selected to process than skip it if (!sub_blocks_water_to_import[sub_block_count]) { continue; } for (int i = sub_block_count * 3; i < sub_block_count * 3 + 3; i++) { int tiles_counter = 0; //set zero to che final tile counter Texture2D sub_piece = sub_blocks_water[i]; //temp array to store the sub mini tiles Texture2D[] bottom_left_mini_tiles, bottom_right_mini_tiles, top_left_mini_tiles, top_right_mini_tiles; //generate the mini tiles to the following computation Tiles_A1_Utility.Generate_Mini_Tile_A1Water(sub_piece, mini_tile_w, mini_tile_h, out bottom_left_mini_tiles, out bottom_right_mini_tiles, out top_left_mini_tiles, out top_right_mini_tiles); if (generate_sprite_sheet_image) { Texture2D sprite_tiles = new Texture2D(wBlock * 8, hBlock * 6); string sprite_sheet_path = string.Format(@"{0}/_Water_{1}_{2}.png", loaded_file_image_path, Path.GetFileNameWithoutExtension(path), i); //generate and iterate the final tile for the subs pieces foreach (KeyValuePair <byte, Texture2D> kvp in Tiles_A1_Utility.Generate_Final_Tiles_A1_Water(mini_tile_w, mini_tile_h, bottom_left_mini_tiles, bottom_right_mini_tiles, top_left_mini_tiles, top_right_mini_tiles, rule_tiles)) { int xx = tiles_counter % 8 * wBlock; int yy = tiles_counter / 8 * hBlock; sprite_tiles.SetPixels(xx, sprite_tiles.height - yy - hBlock, wBlock, hBlock, kvp.Value.GetPixels()); tiles_counter++; } images_path.Add(sprite_sheet_path); File.WriteAllBytes(sprite_sheet_path, sprite_tiles.EncodeToPNG()); AssetDatabase.Refresh(); TextureImporter importer = AssetImporter.GetAtPath(sprite_sheet_path) as TextureImporter; if (importer != null) { importer.textureType = TextureImporterType.Sprite; importer.spriteImportMode = SpriteImportMode.Multiple; importer.filterMode = FilterMode.Point; importer.spritePixelsPerUnit = hBlock; importer.compressionQuality = 0; importer.maxTextureSize = sprite_tiles.width; SpriteMetaData[] tmps = new SpriteMetaData[8 * 6]; string tmpName = Path.GetFileNameWithoutExtension(sprite_sheet_path); for (int j = 0; j < 48; j++) { int xx = j % 8 * wBlock; int yy = (j / 8 + 1) * hBlock; SpriteMetaData smd = new SpriteMetaData(); smd = new SpriteMetaData(); smd.alignment = 0; smd.border = new Vector4(0, 0, 0, 0); smd.name = string.Format("{0}_{1:00}", tmpName, j); smd.pivot = new Vector2(.5f, .5f); smd.rect = new Rect(xx, sprite_tiles.height - yy, wBlock, hBlock); tmps[j] = smd; } importer.spritesheet = tmps; importer.SaveAndReimport(); } } else { //create the directory for the final images string tile_folder_path = string.Format(@"{0}/_Water_{1}_{2}", loaded_file_image_path, Path.GetFileNameWithoutExtension(path), i); //add the path of the this that will contains alla the sub block final tiles images_path.Add(tile_folder_path); if (!Directory.Exists(tile_folder_path)) { Directory.CreateDirectory(tile_folder_path); } //generate and iterate the final tile for the subs pieces foreach (KeyValuePair <byte, Texture2D> kvp in Tiles_A1_Utility.Generate_Final_Tiles_A1_Water(mini_tile_w, mini_tile_h, bottom_left_mini_tiles, bottom_right_mini_tiles, top_left_mini_tiles, top_right_mini_tiles, rule_tiles)) { //save each final tile to its own image var tile_bytes = kvp.Value.EncodeToPNG(); string tile_file_path = string.Format(@"{0}/_Water_{1}_{2}_{3:000}.png", tile_folder_path, Path.GetFileNameWithoutExtension(path), sub_block_count, tiles_counter); File.WriteAllBytes(tile_file_path, tile_bytes); tiles_counter++; } } } } AssetDatabase.Refresh(); //refresh asset database //generate the fixed Auto tiles for (int i = 0; i < images_path.Count; i += 3) { if (generate_sprite_sheet_image) { Tiles_A1_Utility.Generate_A1_Water_Tile_SS(path, images_path[i], images_path[i + 1], images_path[i + 2], rule_tiles, wBlock); } else { Tiles_A1_Utility.Generate_A1_Water_Tile(path, images_path[i], images_path[i + 1], images_path[i + 2], rule_tiles, wBlock); } } }
//Reset all sprite added. public void SetPivot(SpriteRenderer _sprite) { if (_sprite.transform.localPosition.x == 0 && _sprite.transform.localPosition.y == 0) { return; } string path = AssetDatabase.GetAssetPath(_sprite.sprite.texture); TextureImporter ti = (TextureImporter)AssetImporter.GetAtPath(path); if (ti.spritesheet.Length > 1) { ti.isReadable = true; List <SpriteMetaData> newData = new List <SpriteMetaData>(); for (var i = 0; i < ti.spritesheet.Length; i++) { SpriteMetaData tD = ti.spritesheet[i]; if (_sprite.sprite.name == tD.name) { float tXSize = tD.rect.size.x; float tYSize = tD.rect.size.y; float tX = _sprite.transform.localPosition.x / 0.015625f; float tY = _sprite.transform.localPosition.y / 0.015625f; float ttX = tX / tXSize * 0.5f; float ttY = tY / tYSize * 0.5f; float rX = 0.5f - ttX; float rY = 0.5f - ttY; tD.pivot = new Vector2(rX, rY); ti.spritesheet[i] = tD; } newData.Add(tD); } ti.spritesheet = newData.ToArray(); AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); ti.isReadable = false; } else { float tXSize = _sprite.sprite.rect.size.x; float tYSize = _sprite.sprite.rect.size.y; float tX = _sprite.transform.localPosition.x / 0.015625f; float tY = _sprite.transform.localPosition.y / 0.015625f; float ttX = tX / tXSize * 0.5f; float ttY = tY / tYSize * 0.5f; float rX = 0.5f - ttX; float rY = 0.5f - ttY; Vector2 newPivot = new Vector2(rX, rY); ti.spritePivot = newPivot; TextureImporterSettings texSettings = new TextureImporterSettings(); ti.ReadTextureSettings(texSettings); texSettings.spriteAlignment = (int)SpriteAlignment.Custom; ti.SetTextureSettings(texSettings); ti.SaveAndReimport(); } _sprite.transform.localPosition = new Vector3(0, 0, 0); }
void OnGUI() { int i, j; ResetManager(); //Remakes game objects require to operate. e = Event.current; //Gets current event (mouse move, repaint, keyboard press, etc) if (renameId != -1 && (e.keyCode == KeyCode.Return || e.keyCode == KeyCode.KeypadEnter)) { renameId = -1; } if (cmTileSets == null) //Check to make certain there is actually a tileset in the resources/tileset folder. { EditorGUILayout.LabelField("No tilesets found. Retrying."); OnEnable(); } else { string[] names = new string[cmTileSets.Length]; //Gets the name of the tilesets into a useable list for (i = 0; i < cmTileSets.Length; i++) { try { names[i] = cmTileSets[i].name; } catch (System.Exception ex) { Debug.Log("There was an error getting the names of the files. We'll try to reload the tilesets. If this continues to show, please close the script and try remimporting and check your images."); Debug.Log("Full system error: " + ex.Message); OnEnable(); } } //Mode variable to swith between major features. string[] mode = { "Tile Painter", "Help Video" }; //, "Pad Tileset"};// Pad tileset not finished yet, removed to allow for earlier release. You can try it out if you want, but is has issues with larger images and places tiles in the wrong order. curMode = GUILayout.Toolbar(curMode, mode); if (curMode == 0) { //If in standard paint mode, display the proper gui elements for the user to use. EditorGUILayout.BeginHorizontal(); int tmpInt = EditorGUILayout.Popup("Tileset", cmSelectedTileSet, names); if (GUILayout.Button("Reload")) { OnEnable(); } EditorGUILayout.EndHorizontal(); string[] tools = { "Paint", "Erase", "Box Paint" }; //curTool = EditorGUILayout.Popup("Tool", curTool, tools); EditorGUILayout.BeginHorizontal(GUILayout.Width(position.width)); //Causes an error on editor load if the window is visible. //This seems to be a problem with how the gui is drawn the first //loop of the script. It only happens the once, and I can't figure //out why. I've been trying for literally weeks and still can't //find an answer. This is the only known bug, but it doesn't //stop the functionality of the script in any way, and only serves //as an annoying message on unity load or this script being //recompiled. Sorry for this bug. I am looking for a way to remove //this error, but I really am stummped as to why it's happening //and I just can not find an answer online. EditorGUILayout.LabelField("Tool", GUILayout.Width(50)); GUILayout.FlexibleSpace(); curTool = GUILayout.Toolbar(curTool, tools); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Paint With Collider", GUILayout.Width(150)); makeCollider = EditorGUILayout.Toggle(makeCollider); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Highlight Current Layer", GUILayout.Width(150)); highlightLayer = EditorGUILayout.Toggle(highlightLayer, GUILayout.Width(25)); highlightColor = EditorGUILayout.ColorField(highlightColor); EditorGUILayout.EndHorizontal(); if (tmpInt != cmSelectedTileSet) //Forces selection of first tileset if none are selected. { LoadTileset(tmpInt); } cmSelectedTileSet = tmpInt; //sets the selected tileset value i = 0; int columnCount = Mathf.RoundToInt((position.width) / 38) - 2; //figures out how many columns are required for the tileset j = 0; int current = 0; tileScrollPosition = EditorGUILayout.BeginScrollView(tileScrollPosition, false, true, GUILayout.Width(position.width)); //creates scrollbox area for tiles inside of the current tileset. GUILayout.BeginHorizontal(); //Initializing first row for (int q = 0; q < cmSprites.Length; q++) { Sprite child = cmSprites[q]; //for every tile inside the currently selected tileset, add a tile try { if (child.texture.name == names[cmSelectedTileSet] && child.name != names[cmSelectedTileSet]) { //if it's the tiles inside the image, not the entire image Rect newRect = new Rect( child.rect.x / child.texture.width, child.rect.y / child.texture.height, child.rect.width / child.texture.width, child.rect.height / child.texture.height ); //gets the x and y position in pixels of where the image is. Used later for display. if (GUILayout.Button("", GUILayout.Width(34), GUILayout.Height(34))) { //draw a clickable button if (cmSelectedTile != null && !e.control) { //empty the selected tile list if control isn't held. Allows multiselect of tiles. cmSelectedTile.Clear(); cmCurSprite.Clear(); } cmSelectedTile.Add(current); //Adds clicked on tile to list of selected tiles. cmCurSprite.Add(cmCurSprites[current]); } GUI.DrawTextureWithTexCoords(new Rect(5 + (j * 38), 4 + (i * 37), 32, 32), child.texture, newRect, true); //draws tile base on pixels gotten at the beginning of the loop if (cmSelectedTile != null && cmSelectedTile.Contains(current)) { //if the current tile is inside of the list of selected tiles, draw a highlight indicator over the button. if (cmSelectedColor == null) { cmSelectedColor = new Texture2D(1, 1); cmSelectedColor.alphaIsTransparency = true; cmSelectedColor.filterMode = FilterMode.Point; cmSelectedColor.SetPixel(0, 0, new Color(.5f, .5f, 1f, .5f)); cmSelectedColor.Apply(); } GUI.DrawTexture(new Rect(5 + (j * 38), 4 + (i * 37), 32, 32), cmSelectedColor, ScaleMode.ScaleToFit, true); } if (j < columnCount) { j++; } else { // if we have enough columns to fill the scroll area, reset the column count and start a new line of buttons j = 0; i++; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); } current++; } }catch (System.Exception ex) { if (ex.Message.StartsWith("IndexOutOfRangeException")) { Debug.Log("Tileset index was out of bounds, reloading and trying again."); OnEnable(); return; } } } GUILayout.EndHorizontal(); //finish the drawing of tiles EditorGUILayout.EndScrollView(); //Display all of the layers. May be put into a foldout for if there are too many layers. Haven't decided yet. GUILayout.Label("Layers:"); if (GUILayout.Button("Add Layer")) { AddLayer(); } String[] minusPlus = { "-", "+", "x", "r" }; ResetLayers(); layers = ResortLayers(layers); //Sort the layers based on their sorting order instead of name int destroyFlag = -1; for (i = 0; i < layers.Count; i++) { //iterates through layers and displays gui for options. EditorGUILayout.BeginHorizontal(); RectOffset tmpPadding = GUI.skin.button.padding; GUI.skin.button.padding = new RectOffset(3, 3, 3, 3); if (layers[i].gameObject.activeSelf) { if (GUILayout.Button(texVisible, GUILayout.Width(15), GUILayout.Height(15))) { layers[i].gameObject.SetActive(false); } } else { if (GUILayout.Button(texHidden, GUILayout.Width(15), GUILayout.Height(15))) { layers[i].gameObject.SetActive(true); } } GUI.skin.button.padding = tmpPadding; if (i == selectedLayer) { //if selected layer, draw checked checkbox to show it's selected if (i != renameId) { EditorGUILayout.ToggleLeft(layers[i].name + " - " + layers[i].GetComponent <SpriteRenderer>().sortingOrder, true); } else { layers[i].name = EditorGUILayout.TextField(layers[i].name); } } else { //if not the selected layer, and is clicked, set it as the selected layer if (i != renameId) { if (EditorGUILayout.ToggleLeft(layers[i].name + " - " + layers[i].GetComponent <SpriteRenderer>().sortingOrder, false)) { selectedLayer = i; } } else { layers[i].name = EditorGUILayout.TextField(layers[i].name); } } //sets pressed value to -1 if nothing is pressed. int pressed = GUILayout.Toolbar(-1, minusPlus); switch (pressed) { case 0: if (i > 0) { //moves layer and all tiles in it to move away from the camera, and moves the layer above it toward the camera. layers[i - 1].GetComponent <SpriteRenderer>().sortingOrder += 1; int upLayer = layers[i - 1].GetComponent <SpriteRenderer>().sortingOrder; foreach (SpriteRenderer sr in layers[i - 1].GetComponentsInChildren <SpriteRenderer>()) { sr.sortingOrder = upLayer; } //layers[i].GetComponent<SpriteRenderer>().sortingOrder -= 1; int downLayer = layers[i].GetComponent <SpriteRenderer>().sortingOrder -= 1; foreach (SpriteRenderer sr in layers[i].GetComponentsInChildren <SpriteRenderer>()) { sr.sortingOrder = downLayer; } selectedLayer = i - 1; } layers = ResortLayers(layers); break; case 1: if (i < layers.Count - 1) { //moves layer and all tiles in it to move toward the camera, and moves the layer above it away from the camera. layers[i + 1].GetComponent <SpriteRenderer>().sortingOrder -= 1; int upLayer = layers[i + 1].GetComponent <SpriteRenderer>().sortingOrder; foreach (SpriteRenderer sr in layers[i + 1].GetComponentsInChildren <SpriteRenderer>()) { sr.sortingOrder = upLayer; } //layers[i].GetComponent<SpriteRenderer>().sortingOrder += 1; int downLayer = layers[i].GetComponent <SpriteRenderer>().sortingOrder += 1; foreach (SpriteRenderer sr in layers[i].GetComponentsInChildren <SpriteRenderer>()) { sr.sortingOrder = downLayer; } selectedLayer = i + 1; } layers = ResortLayers(layers); break; case 2: //deletes the layer game object, which also deletes all the children destroyFlag = i; break; case 3: if (renameId == -1) { renameId = i; } else { renameId = -1; } break; default: //do nothing if a button wasn't pressed (required or I get errors T_T) break; } EditorGUILayout.EndHorizontal(); //end the layer gui } if (selectedLayer <= layers.Count - 1 && selectedLayer > 0) { //double check to make certain a layer of some sort is selected and is in valid range curLayer = layers[selectedLayer].gameObject; } if (selectedLayer <= layers.Count - 1 && layers[selectedLayer] != null) { ResetHighlight(layers[selectedLayer].gameObject, highlightLayer); curLayer = layers[selectedLayer].gameObject; } else { if (layers.Count - 1 > 0 && layers[selectedLayer] != null) { curLayer = layers[selectedLayer].gameObject; } else { } } if (destroyFlag != -1) { DestroyImmediate(layers[destroyFlag].gameObject); return; //Breaks method to not have errors down the line. Forces reload of tilesets to keep inside the bounds of the array. } destroyFlag = -1; } else if (curMode == 1) { curMode = 0; Application.OpenURL("https://www.youtube.com/watch?v=mxy9HdNM-is"); return; } else if (curMode == 2) { int tmpInt = EditorGUILayout.Popup("Tileset", cmSelectedTileSet, names); if (tmpInt != cmSelectedTileSet) //Forces selection of first tileset if none are selected. { LoadTileset(tmpInt); } cmSelectedTileSet = tmpInt; //sets the selected tileset value GUILayout.BeginHorizontal(); GUILayout.Label("Grid Size X", GUILayout.Width(200)); gridSizeX = EditorGUILayout.IntField(gridSizeX); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Grid Size Y", GUILayout.Width(200)); gridSizeY = EditorGUILayout.IntField(gridSizeY); GUILayout.EndHorizontal(); /*GUILayout.BeginHorizontal(); * GUILayout.Label("Pad Size X", GUILayout.Width(200)); * padSizeX = EditorGUILayout.IntField(padSizeX); * GUILayout.EndHorizontal(); * * GUILayout.BeginHorizontal(); * GUILayout.Label("Pad Size Y", GUILayout.Width(200)); * padSizeY = EditorGUILayout.IntField(padSizeY); * GUILayout.EndHorizontal();*/ if (GUILayout.Button("Generate New Texture")) { List <Rect> listOfNewSlices = new List <Rect>(); Texture2D curTileSet = Resources.Load <Texture2D>("Tilesets/" + cmTileSets[cmSelectedTileSet].name); //cmTileSets[cmSelectedTileSet]; int newWidth = (int)(curTileSet.width + (padSizeX * 2 * (curTileSet.width / gridSizeX))); int newHeight = (int)(curTileSet.height + (((curTileSet.height / gridSizeY)) * (padSizeY * 2))); Texture2D newTileSet = new Texture2D(newWidth, newHeight); Debug.Log("Generated new tile image with a size of " + newTileSet.width + ", " + newTileSet.height); // Debug.Log("Tilecount: " + (int)(curTileSet.width/gridSizeX) + ", " + (int)(curTileSet.height/gridSizeY)); for (j = 0; j < (int)(curTileSet.width / gridSizeX); j++) { for (i = 0; i < (int)(curTileSet.height / gridSizeY); i++) { //Copies old image tiles to new image with padding. try{ newTileSet.SetPixels( ((j * gridSizeX) + (j * padSizeX * 2)) + padSizeX, ((i * gridSizeY) + (i * padSizeY * 2)) + padSizeY, gridSizeX, gridSizeY, curTileSet.GetPixels( j * gridSizeX, i * gridSizeY, gridSizeX, gridSizeY)); Debug.Log(i * 32); //LeftSide /*newTileSet.SetPixels( * (j*gridSizeX)+(j*padSizeX*2)+padSizeX-1, * (i*gridSizeY)+(i*padSizeY*2), * 1, * gridSizeY, * curTileSet.GetPixels( * j*gridSizeX, * i*gridSizeY, * 1, * gridSizeY)); * * //RightSide * newTileSet.SetPixels( * (j*gridSizeX)+(j*padSizeX*2)+padSizeX + gridSizeX, * (i*gridSizeY)+(i*padSizeY*2), * 1, * gridSizeY, * curTileSet.GetPixels( * (j*gridSizeX)+gridSizeX-1, * i*gridSizeY, * 1, * gridSizeY)); * * //BottomSide * newTileSet.SetPixels( * (j*gridSizeX)+(j*padSizeX*2)+padSizeX, * (i*gridSizeY)+(i*padSizeY*2)-1, * gridSizeX, * 1, * curTileSet.GetPixels( * j*gridSizeX, * i*gridSizeY, * gridSizeX, * 1)); * * //TopSide * newTileSet.SetPixels( * (j*gridSizeX)+(j*padSizeX*2)+padSizeX, * (i*gridSizeY)+(i*padSizeY*2)+gridSizeY, * gridSizeX, * 1, * curTileSet.GetPixels( * (j*gridSizeX), * (i*gridSizeY)+gridSizeY-1, * gridSizeX, * 1));*/ listOfNewSlices.Add(new Rect( ((i * gridSizeY) + (i * padSizeY * 2)) + padSizeY, ((j * gridSizeX) + (j * padSizeX * 2)) + padSizeX, gridSizeX, gridSizeY)); //Debug.Log("Drawing tile " + i + ", " + j + " at " + ((i*padSizeX)+(i*gridSizeX)) + ", " + ((j*padSizeY)+(j*gridSizeY)) + " from " + i*gridSizeX + ", " + j*gridSizeY); }catch (System.Exception ex) { Debug.Log("ERROR: " + ex.Message); if (0 == 0) { } } } } newTileSet.Apply(); //listOfNewSlices.Add(new Rect(0,newTileSet.height-gridSizeX,100,100)); Debug.Log("Image generation completed, generating slices."); /*FileStream fs = new FileStream(Application.dataPath + "/Resources/Tilesets/" + curTileSet.name + "_padded.png", FileMode.Append); * BinaryWriter bw = new BinaryWriter(fs); * bw.Write(newTileSet.EncodeToPNG()); * bw.Close(); * fs.Close();*/ //AssetDatabase.CreateAsset(newTileSet.EncodeToPNG(), "Assets/Resources/Tilesets/" + curTileSet.name + "_padded.png"); bool isWriting = true; while (isWriting) { File.WriteAllBytes(Application.dataPath + "/Resources/Tilesets/" + curTileSet.name + "_padded.png", newTileSet.EncodeToPNG()); isWriting = false; } AssetDatabase.Refresh(); TextureImporter ti = new TextureImporter(); ti = (TextureImporter)AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(Resources.Load <Texture>("Tilesets/" + curTileSet.name + "_padded"))); TextureImporterType type = new TextureImporterType(); type = TextureImporterType.Sprite; ti.textureType = type; ti.spritePixelsPerUnit = gridSizeX; ti.spriteImportMode = SpriteImportMode.Multiple; ti.filterMode = FilterMode.Point; List <SpriteMetaData> spriteData = new List <SpriteMetaData>(); //[listOfNewSlices.Count+1]; //listOfNewSlices.Reverse(); for (i = 0; i < listOfNewSlices.Count; i++) { float alpha = 0; foreach (Color pixel in newTileSet.GetPixels((int)listOfNewSlices[i].x, (int)listOfNewSlices[i].y, (int)listOfNewSlices[i].width, (int)listOfNewSlices[i].height)) { alpha += pixel.a; } if (alpha > 0) { listOfNewSlices[i] = new Rect(listOfNewSlices[i].x, listOfNewSlices[i].y, listOfNewSlices[i].width, listOfNewSlices[i].height); SpriteMetaData tmpSpriteData = new SpriteMetaData(); tmpSpriteData.rect = listOfNewSlices[i]; tmpSpriteData.name = curTileSet.name + "_padded_" + i; // ti.spritesheet.GetLength(0); tmpSpriteData.alignment = 0; tmpSpriteData.pivot = new Vector2(gridSizeX / 2, gridSizeY / 2); spriteData.Add(tmpSpriteData); } else { listOfNewSlices.RemoveAt(i); //spriteData.RemoveAt(i); i--; } } ti.spritesheet = spriteData.ToArray(); Debug.Log("Finished generating new padded tileset. Pausing thread to update file."); System.Threading.Thread.Sleep(4000); //Added to allow for saving and reimporting image in unity. Required to run without error. OnEnable(); } if (GUILayout.Button("Regenerate to Original File")) { } } } }
public static new void Generate_Tiles(string path, List <Texture2D> sub_blocks, List <bool> sub_blocks_to_import, int mini_tile_w, int mini_tile_h, int wBlock, int hBlock, bool generate_sprite_sheet_image) { //create the final directory for the auto tile if (!Directory.Exists(Tiles_Utility.Auto_Tile_Folder_Path)) { Directory.CreateDirectory(Tiles_Utility.Auto_Tile_Folder_Path); } //create the final directory for the generated Images if (!Directory.Exists(Tiles_Utility.final_image_folder_path)) { Directory.CreateDirectory(Tiles_Utility.final_image_folder_path); } //create the folder for that specific file image string fileName = Path.GetFileNameWithoutExtension(path); string loaded_file_image_path = string.Format(@"{0}/_{1}", Tiles_Utility.final_image_folder_path, fileName); //ex rtp_import\Outside_A2\single_block_folder\final_tile\Image if (!Directory.Exists(loaded_file_image_path)) { Directory.CreateDirectory(loaded_file_image_path); } List <string> images_path = new List <string>(); //list of the path of the impoted tiles Dictionary <byte, int> rule_tiles = new Dictionary <byte, int>(); //dictionary for the tile rules //foreach sub pieces in the image for (int sub_block_count = 0; sub_block_count < sub_blocks.Count; sub_block_count++) { if (!sub_blocks_to_import[sub_block_count]) { continue; //If the current sub is not selected to process than skip it } int tiles_counter = 0; // counter to enumerate the sprite Texture2D sub_piece = sub_blocks[sub_block_count]; //get the texture //temp array to store the sub mini tiles Texture2D[] bottom_left_mini_tiles, bottom_right_mini_tiles, top_left_mini_tiles, top_right_mini_tiles; //generate the mini tiles to the following computation RPGM_XP_Utility.Generate_Mini_Tile_RPGMXP(sub_piece, mini_tile_w, mini_tile_h, out bottom_left_mini_tiles, out bottom_right_mini_tiles, out top_left_mini_tiles, out top_right_mini_tiles); Texture2D sprite_tiles = new Texture2D(wBlock * 8, hBlock * 6); int sprite_tile_width = wBlock * 8; string sprite_sheet_path = string.Format(@"{0}/_{1}_{2}.png", loaded_file_image_path, Path.GetFileNameWithoutExtension(path), sub_block_count); //generate and iterate the final tile for the subs pieces foreach (KeyValuePair <byte, Texture2D> kvp in RPGM_XP_Utility.Generate_Final_Tiles_RPGMXP(mini_tile_w, mini_tile_h, bottom_left_mini_tiles, bottom_right_mini_tiles, top_left_mini_tiles, top_right_mini_tiles, rule_tiles)) { int xx = tiles_counter % 8 * wBlock; int yy = tiles_counter / 8 * hBlock; sprite_tiles.SetPixels(xx, sprite_tiles.height - yy - hBlock, wBlock, hBlock, kvp.Value.GetPixels()); tiles_counter++; } images_path.Add(sprite_sheet_path); File.WriteAllBytes(sprite_sheet_path, sprite_tiles.EncodeToPNG()); AssetDatabase.Refresh(); TextureImporter importer = AssetImporter.GetAtPath(sprite_sheet_path) as TextureImporter; if (importer != null) { importer.textureType = TextureImporterType.Sprite; importer.spriteImportMode = SpriteImportMode.Multiple; importer.filterMode = FilterMode.Point; importer.spritePixelsPerUnit = hBlock; importer.compressionQuality = 0; importer.maxTextureSize = sprite_tile_width; SpriteMetaData[] tmps = new SpriteMetaData[8 * 6]; string tmpName = Path.GetFileNameWithoutExtension(sprite_sheet_path); for (int i = 0; i < 48; i++) { int xx = i % 8 * wBlock; int yy = (i / 8 + 1) * hBlock; SpriteMetaData smd = new SpriteMetaData(); smd = new SpriteMetaData(); smd.alignment = 0; smd.border = new Vector4(0, 0, 0, 0); smd.name = string.Format("{0}_{1:00}", tmpName, i); smd.pivot = new Vector2(.5f, .5f); smd.rect = new Rect(xx, sprite_tiles.height - yy, wBlock, hBlock); tmps[i] = smd; } importer.spritesheet = tmps; importer.SaveAndReimport(); } } AssetDatabase.Refresh(); //refresh asset database //generate the A2_tile Auto tiles for (int i = 0; i < images_path.Count; i += 1) { string str = images_path[i]; Tiles_A2_Utility.Generate_A2_Tile_SS(path, str, rule_tiles); } }
private void ImportSpriteSheetIntoAnimation(Texture2D spriteSheet, int animIdx = -1) { string assetPath = AssetDatabase.GetAssetPath(spriteSheet); if (string.IsNullOrEmpty(assetPath)) { return; } TextureImporter spriteSheetImporter = (TextureImporter)TextureImporter.GetAtPath(assetPath); int characterNb; int charRowLength; int charColumnLength; int charFramesCount = m_target.DirectionsPerAnim * m_target.FramesPerAnim; int columns = 0, rows = 0; if (spriteSheetImporter.textureType != TextureImporterType.Sprite || spriteSheetImporter.spriteImportMode != SpriteImportMode.Multiple || spriteSheetImporter.spritesheet.Length == 0 || spriteSheetImporter.spritesheet.Length % charFramesCount != 0) { Rect[] rects = InternalSpriteUtility.GenerateAutomaticSpriteRectangles(spriteSheet, 4, 0); if (rects.Length > 0 && rects.Length % charFramesCount == 0) { for (; columns < rects.Length; ++columns) { //NOTE: the order of slicing in GenerateAutomaticSpriteRectangles is from bottom to top, not from top to bottom like Sprite Editor Slicing if (rects[columns].yMin >= rects[0].yMax) { rows = rects.Length / columns; break; } } } else { columns = m_target.FramesPerAnim; rows = m_target.DirectionsPerAnim; } charRowLength = Mathf.Max(1, columns / m_target.FramesPerAnim); charColumnLength = Mathf.Max(1, rows / m_target.FramesPerAnim); characterNb = charRowLength * charColumnLength; int spriteCount = charFramesCount * characterNb; SpriteMetaData[] aSpriteMetaData = spriteSheetImporter.spritesheet; if (spriteSheetImporter.spritesheet.Length != spriteCount || spriteSheetImporter.spriteImportMode != SpriteImportMode.Multiple) { aSpriteMetaData = new SpriteMetaData[spriteCount]; spriteSheetImporter.textureType = TextureImporterType.Sprite; spriteSheetImporter.spriteImportMode = SpriteImportMode.Multiple; spriteSheetImporter.filterMode = FilterMode.Point; spriteSheetImporter.mipmapEnabled = false; spriteSheetImporter.textureFormat = TextureImporterFormat.AutomaticTruecolor; Rect spriteRect = new Rect(0, 0, spriteSheet.width / (m_target.FramesPerAnim * charRowLength), spriteSheet.height / (m_target.DirectionsPerAnim * charColumnLength)); for (int gy = 0, spriteIdx = 0; gy < rows; ++gy) { for (int gx = 0; gx < columns; ++gx, ++spriteIdx) { spriteRect.position = new Vector2(gx * spriteRect.width, spriteSheet.height - (1 + gy) * spriteRect.height); SpriteMetaData spriteMetaData = new SpriteMetaData(); //int characterIdx = (gy / m_target.DirectionNb) * charRowLength + (gx / m_target.FramesPerAnim); //NOTE: the sprites are sorted alphabetically, so spriteIdx should be in the first place after the name and nothing else spriteMetaData.name = spriteSheet.name + "_" + spriteIdx; // + (characterNb > 1 ? ("_" + characterIdx) : "") + "_" + gy + "_" + gx; spriteMetaData.rect = spriteRect; aSpriteMetaData[spriteIdx] = spriteMetaData; } } spriteSheetImporter.spritesheet = aSpriteMetaData; AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); } } UpdateAligmentAndPivot(spriteSheet); List <Sprite> sprites = new List <Sprite>(AssetDatabase.LoadAllAssetsAtPath(assetPath).OfType <Sprite>().ToArray()); //sort them properly using the last number sprites = sprites.OrderBy(s => int.Parse(s.name.Substring(s.name.LastIndexOf("_") + 1))).ToList(); for (; columns < sprites.Count; ++columns) { if (sprites[columns].rect.yMax <= sprites[0].rect.yMin) { rows = sprites.Count / columns; break; } } if (columns * rows != sprites.Count || columns % m_target.FramesPerAnim != 0 || rows % m_target.DirectionsPerAnim != 0) { Debug.LogError("Something was wrong with the sprite sheet. Try slicing it again using the Sprite Editor using grid settings or set the Sprite Mode to single and try again."); return; } List <Sprite> sortedSprites = new List <Sprite>(); charRowLength = Mathf.Max(1, columns / m_target.FramesPerAnim); charColumnLength = Mathf.Max(1, rows / m_target.FramesPerAnim); for (int charY = 0; charY < charColumnLength; ++charY) { for (int charX = 0; charX < charRowLength; ++charX) { for (int c = 0; c < m_target.DirectionsPerAnim; ++c) { for (int r = 0; r < m_target.FramesPerAnim; ++r) { int gx = charX * m_target.FramesPerAnim + r; int gy = charY * m_target.DirectionsPerAnim + c; sortedSprites.Add(sprites[gy * columns + gx]); } } } } characterNb = sortedSprites.Count / charFramesCount; if (animIdx >= 0) { ImportSpriteSheetIntoAnimation(spriteSheet, sortedSprites.Take(charFramesCount).ToArray(), animIdx, spriteSheet.name); } else { for (int characterIdx = 0; characterIdx < characterNb; ++characterIdx) { Sprite[] characterSprites = sortedSprites.Skip(characterIdx * charFramesCount).Take(charFramesCount).ToArray(); string charName = spriteSheet.name + (characterNb > 1? ("_" + characterIdx) : ""); ImportSpriteSheetIntoAnimation(spriteSheet, characterSprites, m_target.GetAnimList().FindIndex(x => x.name == charName), charName); } } }
void OnGUI() { if (m_boxSkin == null) { m_boxSkin = new GUIStyle("Box"); m_boxSkin.normal.background = new Texture2D(1, 1); m_boxSkin.normal.background.hideFlags = HideFlags.DontSave; } //EditorGUILayout.Foldout(false, "Selection Settings"); // Check if sprite renderer has changed to update the sprite texture importer GameObject prevObj = m_selectedObj; m_selectedObj = Selection.activeGameObject; if (prevObj != m_selectedObj || m_sprRenderer == null) { m_sprRenderer = m_selectedObj != null?m_selectedObj.GetComponent <SpriteRenderer>() : null; m_sprite = null; m_sprTexImporter = null; } // Check if sprite has changed to update m_sprTexImporter Sprite prevSprite = m_sprite; m_sprite = m_sprRenderer != null ? m_sprRenderer.sprite : null; if (prevSprite != m_sprite && m_sprite != null) { m_sprTexImporter = null; string spritePath = AssetDatabase.GetAssetPath(m_sprRenderer.sprite); if (!string.IsNullOrEmpty(spritePath)) { m_sprTexImporter = AssetImporter.GetAtPath(spritePath) as TextureImporter; } } if (m_sprRenderer == null) { EditorGUILayout.HelpBox("Select a sprite first", MessageType.Info); } // draw sprite sheet if (m_sprTexImporter != null && m_sprTexImporter.spritesheet != null) { EditorGUI.BeginChangeCheck(); Color bgColor = EditorGUILayout.ColorField(m_boxSkin.normal.background.GetPixel(0, 0)); if (EditorGUI.EndChangeCheck()) { m_boxSkin.normal.background.SetPixel(0, 0, bgColor); m_boxSkin.normal.background.Apply(); } m_sprScrollView = GUILayout.BeginScrollView(m_sprScrollView); { GUILayout.Box(m_sprRenderer.sprite.texture, m_boxSkin); Rect rSprSheet = GUILayoutUtility.GetLastRect(); rSprSheet.position += Vector2.one; // add the border pixel if (Event.current.button == 0 && (Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseUp)) { Vector2 mouseRelPos = Event.current.mousePosition - rSprSheet.position; mouseRelPos.y = m_sprRenderer.sprite.texture.height - mouseRelPos.y; for (int i = 0; i < m_sprTexImporter.spritesheet.Length; ++i) { SpriteMetaData sprMetaData = m_sprTexImporter.spritesheet[i]; if (sprMetaData.rect.Contains(mouseRelPos)) { string spritePath = AssetDatabase.GetAssetPath(m_sprRenderer.sprite); Sprite selSprite = (Sprite)AssetDatabase.LoadAllAssetsAtPath(spritePath).First(x => x is Sprite && x.name == sprMetaData.name); if (Event.current.type == EventType.MouseUp) { if (selSprite != m_sprRenderer.sprite) { Undo.RecordObject(m_sprRenderer, "Changed Sprite"); EditorUtility.SetDirty(m_sprRenderer); } m_sprRenderer.sprite = selSprite; // Apply to all selected sprites for (int objIdx = 0; objIdx < Selection.gameObjects.Length; ++objIdx) { SpriteRenderer sprRenderer = Selection.gameObjects[objIdx].GetComponent <SpriteRenderer>(); if (sprRenderer != null && sprRenderer != m_sprRenderer) { if (sprRenderer.sprite != m_sprRenderer.sprite) { Undo.RecordObject(sprRenderer, "Changed Sprite"); EditorUtility.SetDirty(sprRenderer); } sprRenderer.sprite = m_sprRenderer.sprite; } } } break; } } } } GUILayout.EndScrollView(); } }
static void ParseXML() { if (Selection.activeObject && Selection.activeObject is TextAsset) { string xmlPath = AssetDatabase.GetAssetPath(Selection.activeObject); string xml = AssetDatabase.LoadAssetAtPath <TextAsset>(xmlPath).text.ToString(); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xml); XmlNode root = xmlDoc.SelectSingleNode("TextureAtlas"); XmlElement rootEle = (XmlElement)root; string imagePath = ""; if (rootEle.HasAttribute("imagePath")) { imagePath = rootEle.GetAttribute("imagePath"); } else if (rootEle.HasAttribute("name")) { imagePath = rootEle.GetAttribute("name") + ".png"; } imagePath = xmlPath.Substring(0, xmlPath.LastIndexOf('/')) + "/" + imagePath; Texture2D t = AssetDatabase.LoadAssetAtPath <Texture2D>(imagePath); if (t == null) { return; } XmlNodeList nodeList = root.ChildNodes; List <SpriteMetaData> metaDatas = new List <SpriteMetaData>(); //遍历所有子节点 foreach (XmlNode xn in nodeList) { if (!(xn is XmlElement)) { continue; } XmlElement xe = (XmlElement)xn; string name = xe.GetAttribute("name").Replace('/', '_'); float x = float.Parse(xe.GetAttribute("x")); float y = float.Parse(xe.GetAttribute("y")); float w = float.Parse(xe.GetAttribute("width")); float h = float.Parse(xe.GetAttribute("height")); // float fx = x; // float fy = y; // float fw = w; // float fh = h; // if(xe.HasAttribute("fx")) // fx = float.Parse( xe.GetAttribute("frameX")); // if(xe.HasAttribute("fy")) // fy = float.Parse( xe.GetAttribute("frameY")); // if(xe.HasAttribute("fw")) // fw = float.Parse( xe.GetAttribute("frameWidth")); // if(xe.HasAttribute("fh")) // fh = float.Parse( xe.GetAttribute("frameHeight")); SpriteMetaData metaData = new SpriteMetaData(); metaData.name = name; metaData.rect = new Rect(x, t.height - h - y, w, h); metaDatas.Add(metaData); } if (metaDatas.Count > 0) { string textureAtlasPath = AssetDatabase.GetAssetPath(t); TextureImporter textureImporter = AssetImporter.GetAtPath(textureAtlasPath) as TextureImporter; textureImporter.maxTextureSize = 2048; textureImporter.spritesheet = metaDatas.ToArray(); textureImporter.textureType = TextureImporterType.Sprite; textureImporter.spriteImportMode = SpriteImportMode.Multiple; textureImporter.spritePixelsPerUnit = 100; AssetDatabase.ImportAsset(textureAtlasPath, ImportAssetOptions.ForceUpdate); } } }
static public bool BuildAtlas(TrimType trimType, List <SpriteElement> listSprite, Dictionary <string, EAPInfoAttachment> dicPivot, string texturePath, int padingSize, bool append = false) { try { //bool checkAppend=append; float prog = 0.2f; EditorUtility.DisplayCancelableProgressBar("Creating Spritesheet", "Auto Build Atlas Sprites", prog); Texture2D[] textArray = new Texture2D[listSprite.Count]; for (int i = 0; i < textArray.Length; i++) { textArray[i] = listSprite[i].texture; } Texture2D mainTexture = new Texture2D(8192, 8192); Rect[] rects = mainTexture.PackTextures(textArray, padingSize, 8192, false); mainTexture.Apply(); //ImportTextureUtil.MaxImportSettings(mainTexture); int xmin = 0; int ymin = 0; int cacheWidth = mainTexture.width; int cacheHeight = mainTexture.height; int optimizeWidth = cacheWidth; int optimizeHeight = cacheHeight; Texture2D mainTexture2 = null; prog = 0.4f; EditorUtility.DisplayCancelableProgressBar("Creating Spritesheet", "Auto Build Atlas Sprites", prog); #region Trim to minimum Texture if (trimType == TrimType.TrimMinimum && rects.Length > 0) { float rectMinX = rects[0].xMin; float rectMinY = rects[0].yMin; float rectMaxX = rects[0].xMax; float rectMaxY = rects[0].yMax; for (int i = 1; i < rects.Length; i++) { if (rects[i].xMin < rectMinX) { rectMinX = rects[i].xMin; } if (rects[i].yMin < rectMinY) { rectMinY = rects[i].yMin; } if (rects[i].xMax < rectMaxX) { rectMaxX = rects[i].xMax; } if (rects[i].yMax < rectMaxY) { rectMaxY = rects[i].yMax; } } int intRectMinX = (int)(rectMinX * cacheWidth); int intRectMinY = (int)(rectMinY * cacheHeight); int intRectMaxX = (int)(rectMaxX * cacheWidth); int intRectMaxY = (int)(rectMaxY * cacheHeight); Color32[] pixels = mainTexture.GetPixels32(); xmin = mainTexture.width; int xmax = 0; ymin = mainTexture.height; int ymax = 0; int oldWidth = mainTexture.width; int oldHeight = mainTexture.height; // Trim 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 - 1) { ymax = y + 1; } if (x < xmin) { xmin = x; } if (x > xmax - 1) { xmax = x + 1; } } } } if (xmin > intRectMinX) { xmin = intRectMinX; } if (ymin > intRectMinY) { ymin = intRectMinY; } if (xmax < intRectMaxX) { xmax = intRectMaxX; } if (ymax < intRectMaxY) { ymax = intRectMaxY; } if (xmax - xmin > 0 && ymax - ymin > 0) { optimizeWidth = xmax - xmin; optimizeHeight = ymax - ymin; mainTexture2 = new Texture2D(xmax - xmin, ymax - ymin); mainTexture2.SetPixels(mainTexture.GetPixels(xmin, ymin, xmax - xmin, ymax - ymin)); mainTexture2.Apply(); GameObject.DestroyImmediate(mainTexture); mainTexture = mainTexture2; } } #endregion prog = 0.5f; EditorUtility.DisplayCancelableProgressBar("Creating Spritesheet", "Auto Build Atlas Sprites", prog); #region Write New File byte[] byt = mainTexture.EncodeToPNG(); if (texturePath != "") { System.IO.File.WriteAllBytes(texturePath, byt); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); } AssetDatabase.ImportAsset(texturePath); #endregion EditorUtility.ClearProgressBar(); prog = 0.6f; EditorUtility.DisplayCancelableProgressBar("Creating Spritesheet", "Auto Build Atlas Sprites", prog); mainTexture = AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)) as Texture2D; TextureImporter ti = AssetImporter.GetAtPath(texturePath) as TextureImporter; TextureImporterSettings settings = new TextureImporterSettings(); ti.ReadTextureSettings(settings); SpriteMetaData[] lstMetaSprite = new SpriteMetaData[listSprite.Count]; if (append) { if (ti.spritesheet != null && ti.spritesheet.Length > 0) { append = true; lstMetaSprite = ti.spritesheet; } else { append = false; } } for (int i = 0; i < lstMetaSprite.Length; i++) { if (i < rects.Length) { SpriteMetaData metaSprite = new SpriteMetaData(); if (append) { metaSprite = lstMetaSprite[i]; } metaSprite.name = listSprite[i].name; Rect rectInfo = listSprite[i].GetSpriteRect(); Rect rect = new Rect(rects[i].x * cacheWidth - xmin, rects[i].y * cacheHeight - ymin, rectInfo.width, rectInfo.height); if (rect.x + rect.width > optimizeWidth) { rect.width = optimizeWidth - rect.x; } if (rect.y + rect.height > optimizeHeight) { rect.height = optimizeHeight - rect.y; } metaSprite.rect = rect; int oWidth = listSprite[i].originalRect.width; int oHeight = listSprite[i].originalRect.height; if (oWidth < 1) { oWidth = 1; } if (oHeight < 1) { oHeight = 1; } int xLeft = listSprite[i].startX; int yTop = listSprite[i].startY; if (listSprite[i].IsOptimize()) { float pivotX = listSprite[i].pivot.x * listSprite[i].originalRect.width; float pivotY = listSprite[i].pivot.y * listSprite[i].originalRect.height; pivotX = pivotX - xLeft; pivotY = pivotY - yTop; pivotX = pivotX / listSprite[i].optimizeRect.width; pivotY = pivotY / listSprite[i].optimizeRect.height; listSprite[i].SetPivot(new Vector2(pivotX, pivotY)); metaSprite.pivot = new Vector2(pivotX, pivotY); metaSprite.alignment = ImportTextureUtil.GetAlignment(metaSprite.pivot); // listSprite[i].alignment; if (dicPivot != null) { foreach (KeyValuePair <string, EAPInfoAttachment> pair in dicPivot) { if (pair.Value.spriteName == metaSprite.name) { pair.Value.SetCache(xLeft, yTop, listSprite[i].originalRect, listSprite[i].optimizeRect); } } } } else { metaSprite.pivot = listSprite[i].pivot; metaSprite.alignment = ImportTextureUtil.GetAlignment(metaSprite.pivot); } lstMetaSprite[i] = metaSprite; } } prog = 0.7f; EditorUtility.DisplayCancelableProgressBar("Creating Spritesheet", "Auto Build Atlas Sprites", prog); ti.isReadable = true; ti.mipmapEnabled = false; ti.spritesheet = lstMetaSprite; ti.textureType = TextureImporterType.Sprite; ti.spriteImportMode = SpriteImportMode.Multiple; ti.spritePixelsPerUnit = 100; settings.textureFormat = TextureImporterFormat.ARGB32; settings.npotScale = TextureImporterNPOTScale.None; settings.alphaIsTransparency = true; ti.SetTextureSettings(settings); ti.maxTextureSize = 4096; ti.mipmapEnabled = false; ti.spriteImportMode = SpriteImportMode.Multiple; AssetDatabase.ImportAsset(texturePath); EditorUtility.SetDirty(mainTexture); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); AssetDatabase.ImportAsset(texturePath); prog = 1.0f; EditorUtility.DisplayCancelableProgressBar("Creating Spritesheet", "Auto Build Atlas Sprites", prog); EditorUtility.ClearProgressBar(); // douple setting for fix Unity 5.5 ti.textureType = TextureImporterType.Sprite; ti.spriteImportMode = SpriteImportMode.Multiple; EditorUtility.SetDirty(mainTexture); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); AssetDatabase.ImportAsset(texturePath); /*for(int i=0;i<listSprite.Count;i++) * { * listSprite[i].FreeMemory(); * }*/ System.GC.Collect(); return(true); } catch (UnityException ex) { Debug.LogError("Error:" + ex.Message); EditorUtility.ClearProgressBar(); return(false); } catch (System.Exception ex) { Debug.LogError("Error:" + ex.Message); EditorUtility.ClearProgressBar(); return(false); } }
static public bool UpdateAtlasSpriteInfo(string pathOutput, List <DataAnimAnalytics> listAnim, float scale) { //Debug.LogError(scale); if (listAnim.Count < 1) { return(false); } Dictionary <string, EAPInfoAttachment> dicPivotCache = new Dictionary <string, EAPInfoAttachment>(); for (int i = 0; i < listAnim.Count; i++) { DataAnimAnalytics dataAnalytic = listAnim[i]; //Debug.LogError(Pathfinding.Serialization.JsonFx.JsonWriter.Serialize(dataAnalytic.jsonFinal)); foreach (KeyValuePair <string, EAPInfoAttachment> pair in dataAnalytic.jsonFinal.dicPivot) { dicPivotCache[pair.Value.spriteName] = pair.Value; } } Dictionary <string, List <EAPInfoAttachment> > dicPivot = new Dictionary <string, List <EAPInfoAttachment> >(); for (int i = 0; i < listAnim.Count; i++) { DataAnimAnalytics dataAnalytic = listAnim[i]; foreach (KeyValuePair <string, EAPInfoAttachment> pair in dataAnalytic.jsonFinal.dicPivot) { List <EAPInfoAttachment> list = null; dicPivot.TryGetValue(pair.Value.spriteName, out list); if (list == null) { list = new List <EAPInfoAttachment>(); } bool haveExist = false; for (int x = 0; x < list.Count; x++) { if (list[x].spriteName == pair.Key) { haveExist = true; break; } } if (!haveExist) { list.Add(pair.Value); } dicPivot[pair.Value.spriteName] = list; } } TextureImporter ti = AssetImporter.GetAtPath(pathOutput) as TextureImporter; TextureImporterSettings settings = new TextureImporterSettings(); ti.ReadTextureSettings(settings); SpriteMetaData[] lstMetaSprite = ti.spritesheet; Dictionary <string, SpriteMetaData> dicSpriteMeta = new Dictionary <string, SpriteMetaData>(); bool haveNew = false; for (int i = 0; i < lstMetaSprite.Length; i++) { SpriteMetaData spriteMetaData = lstMetaSprite[i]; if (Mathf.Abs(scale - 1f) > Mathf.Epsilon) { Rect rect = spriteMetaData.rect; rect.x = rect.x * scale; rect.y = rect.y * scale; rect.width = rect.width * scale; rect.height = rect.height * scale; spriteMetaData.rect = rect; haveNew = true; } dicSpriteMeta[lstMetaSprite[i].name] = spriteMetaData; } foreach (KeyValuePair <string, List <EAPInfoAttachment> > pair in dicPivot) { List <EAPInfoAttachment> list = pair.Value; for (int i = 0; i < list.Count; i++) { if (!dicSpriteMeta.ContainsKey(list[i].spriteName)) // sprite new { if (dicSpriteMeta.ContainsKey(list[i].spriteName)) { SpriteMetaData currentMeta = dicSpriteMeta[list[i].spriteName]; SpriteMetaData metaSprite = new SpriteMetaData(); metaSprite.name = list[i].spriteName; metaSprite.rect = currentMeta.rect; metaSprite.alignment = currentMeta.alignment; EAPInfoAttachment pivotCache = null; dicPivotCache.TryGetValue(list[i].spriteName, out pivotCache); if (pivotCache == null) { pivotCache = list[i]; } //Debug.LogError(pivotCache.name+","+list[i].name+","+pivotCache.name+","+pivotCache.isOptimze); if (!pivotCache.isOptimze) { metaSprite.pivot = new Vector2(list[i].x, list[i].y); //currentMeta.pivot; } else { float pivotX = list[i].x * pivotCache.originalRect.width * scale; float pivotY = list[i].y * pivotCache.originalRect.height * scale; float oWidth = pivotCache.optimizeRect.width * scale; float oHeight = pivotCache.optimizeRect.height * scale; if (oWidth < 1) { oWidth = 1; } if (oHeight < 1) { oHeight = 1; } pivotX = pivotX - pivotCache.startX * scale; pivotY = pivotY - pivotCache.startY * scale; pivotX = pivotX / oWidth; pivotY = pivotY / oHeight; metaSprite.pivot = new Vector2(pivotX, pivotY); } dicSpriteMeta[metaSprite.name] = metaSprite; haveNew = true; } } } } if (haveNew) { Texture2D mainTexture = AssetDatabase.LoadAssetAtPath(pathOutput, typeof(Texture2D)) as Texture2D; lstMetaSprite = new SpriteMetaData[dicSpriteMeta.Count]; int count = 0; foreach (KeyValuePair <string, SpriteMetaData> pair in dicSpriteMeta) { lstMetaSprite[count] = pair.Value; count++; } ti.isReadable = true; ti.mipmapEnabled = false; ti.spritesheet = lstMetaSprite; ti.textureType = TextureImporterType.Sprite; ti.spriteImportMode = SpriteImportMode.Multiple; ti.spritePixelsPerUnit = 100; settings.textureFormat = TextureImporterFormat.ARGB32; settings.npotScale = TextureImporterNPOTScale.None; settings.alphaIsTransparency = true; ti.SetTextureSettings(settings); ti.maxTextureSize = 4096; ti.mipmapEnabled = false; ti.spriteImportMode = SpriteImportMode.Multiple; AssetDatabase.ImportAsset(pathOutput); EditorUtility.SetDirty(mainTexture); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); AssetDatabase.ImportAsset(pathOutput); } return(true); }