private static void CreateAtlasRaw() { var path = AssetDatabase.GetAssetPath(Selection.activeObject); path = string.IsNullOrEmpty(path) ? "Assets" : path; if (File.Exists(path)) { path = Path.GetDirectoryName(path); } var atlas = CreateInstance <AtlasRaw>(); atlas.bins = new BinRaw[0]; var setting = new PackSetting(); atlas.maxSize = setting.maxAtlasSize; atlas.padding = setting.padding; atlas.isPOT = setting.isPOT; atlas.forceSquare = setting.forceSquare; var assetPath = Path.Combine(path, PackConst.DefaultAtlasAssetName); assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath); atlas.id = PackUtil.GenerateAtlasId(); AssetDatabase.CreateAsset(atlas, assetPath); Selection.activeObject = AssetDatabase.LoadAssetAtPath <AtlasRaw>(assetPath); }
public PackSetting(PackSetting data) { maxAtlasSize = data.maxAtlasSize; padding = data.padding; isPOT = data.isPOT; forceSquare = data.forceSquare; }
public static AtlasRaw Pack(string targetFolder, IPackSprite[] textures, PackSetting setting) { EditorUtility.DisplayProgressBar("", "generate atlas...", 0.5f); var atlasPath = Path.Combine(targetFolder, PackConst.DefaultAtlasAssetName); atlasPath = AssetDatabase.GenerateUniqueAssetPath(atlasPath); var atlasRaw = new PackAtlas(setting, atlasPath, textures).GenerateAtlas(); EditorUtility.ClearProgressBar(); return(atlasRaw); }
public void Setup(PackSetting setting, BinRaw bin) { this.setting = setting; this.bin = bin; mainAsset = bin.main; mainAssetPath = AssetDatabase.GetAssetPath(mainAsset); mainImporter = AssetImporter.GetAtPath(mainAssetPath) as TextureImporter; if (bin.addition != null) { addAsset = bin.addition; addAssetPath = AssetDatabase.GetAssetPath(addAsset); addImporter = AssetImporter.GetAtPath(addAssetPath) as TextureImporter; } transparency = PackUtil.CheckAtlasBinTranparency(bin); maxTextureSize = PackUtil.Scale2POT(Mathf.Max((int)bin.size.x, (int)bin.size.y)); }
public PackAtlas(PackSetting setting, string atlasPath, IPackSprite[] sprites) { mSetting = setting; mAtlasPath = atlasPath; mSprites = sprites; }
/// <summary> /// Translate by sprite's type /// </summary> /// <param name="targetFolder">Target folder for generating atlas or sprite.</param> /// <param name="forward">If true, translate sprite to atlas, else translate atlas to sprite</param> public void Translate(string targetFolder, bool forward, string resourceFolder = null, PackSetting setting = null) { var collectors = new List <ICollector>(); var transfer = new List <UnityEngine.UI.Sprite>(); var exclude = new List <UnityEngine.UI.Sprite>(); var prefabs = AssetDatabase.FindAssets("t:prefab").Select(i => AssetDatabase.GUIDToAssetPath(i)).ToArray(); for (int i = 0; i < prefabs.Length; i++) { EditorUtility.DisplayProgressBar("Prefab", prefabs[i], (float)i / prefabs.Length); var prefabCollector = new PrefabCollector(); prefabCollector.path = prefabs[i]; prefabCollector.Collect(); collectors.Add(prefabCollector); transfer.AddRange(prefabCollector.sprites); } var scenes = AssetDatabase.FindAssets("t:scene").Select(i => AssetDatabase.GUIDToAssetPath(i)).ToArray(); for (int i = 0; i < scenes.Length; i++) { EditorUtility.DisplayProgressBar("Scene", scenes[i], (float)i / scenes.Length); var sceneCollector = new SceneCollector(); sceneCollector.path = scenes[i]; sceneCollector.Collect(); collectors.Add(sceneCollector); transfer.AddRange(sceneCollector.sprites); } var clips = AssetDatabase.FindAssets("t:animationclip").Select(i => AssetDatabase.GUIDToAssetPath(i)).ToArray(); for (int i = 0; i < clips.Length; i++) { EditorUtility.DisplayProgressBar("AnimationClip", clips[i], (float)i / scenes.Length); var clipCollector = new AnimationClipCollector(); clipCollector.path = clips[i]; clipCollector.Collect(); exclude.AddRange(clipCollector.sprites); } // 过滤类型不符的sprite,过滤在AnimationClip引用的sprite,过滤不在resourceFolder中的资源 for (int i = transfer.Count - 1; i >= 0; i--) { if (transfer[i] != null && ((transfer[i].type == UnityEngine.UI.Sprite.Type.Sprite) != forward || exclude.Any(e => e == transfer[i]))) { transfer[i] = null; } } if (!string.IsNullOrEmpty(resourceFolder)) { for (int i = transfer.Count - 1; i >= 0; i--) { if (transfer[i] != null) { var transferPath = ""; if (transfer[i].type == UnityEngine.UI.Sprite.Type.Sprite) { transferPath = AssetDatabase.GetAssetPath(transfer[i].sprite); } else if (transfer[i].type == UnityEngine.UI.Sprite.Type.Atlas) { transferPath = AssetDatabase.GetAssetPath(transfer[i].atlasRaw); } if (!transferPath.Contains(resourceFolder)) { transfer[i] = null; } } } } if (forward) { MapSprite2Atlas(targetFolder, setting, transfer); } else { MapAtlas2Sprite(targetFolder, transfer); } Util.RebindThenTranslate(collectors, transfer); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); EditorUtility.ClearProgressBar(); }
private static void MapSprite2Atlas(string targetFolder, PackSetting setting, List <UnityEngine.UI.Sprite> sprites) { var spritePaths = new List <string>(); foreach (var sprite in sprites) { if (sprite != null && sprite.type == UnityEngine.UI.Sprite.Type.Sprite) { var path = AssetDatabase.GetAssetPath(sprite.sprite); if (!string.IsNullOrEmpty(path) && !spritePaths.Contains(path)) { spritePaths.Add(path); } } } var pathSpriteMap = new Dictionary <string, UnityEngine.UI.Sprite>(); var spriteGroups = spritePaths.GroupBy(path => { var importer = AssetImporter.GetAtPath(path) as TextureImporter; return(importer.spritePackingTag); }); foreach (var group in spriteGroups) { var groupPaths = group.ToArray(); var groupNames = Util.MapSpritePath2SpriteNameInAtlas(groupPaths); var groupSprites = new PackAssetSprite[groupPaths.Length]; for (int i = 0; i < groupPaths.Length; i++) { groupSprites[i] = new PackAssetSprite(groupPaths[i]) { name = groupNames[i] }; groupSprites[i].quality = PackUtil.CheckTextureCompressed(groupPaths[i]) ? PackQuality.AlphaSplit : PackQuality.Full; } var groupTag = string.IsNullOrEmpty(group.Key) ? EmptyTagName : group.Key; var groupFolder = Path.Combine(targetFolder, groupTag); if (!Directory.Exists(groupFolder)) { Directory.CreateDirectory(groupFolder); } var atlasRaw = AtlasPacker.Pack(groupFolder, groupSprites, setting); for (int i = 0; i < groupPaths.Length; i++) { pathSpriteMap[groupPaths[i]] = new UnityEngine.UI.Sprite(atlasRaw, groupNames[i]); } } ; for (int i = 0; i < sprites.Count; i++) { var sprite = sprites[i]; if (sprite != null && sprite.type == UnityEngine.UI.Sprite.Type.Sprite) { var path = AssetDatabase.GetAssetPath(sprite.sprite); if (!string.IsNullOrEmpty(path)) { sprites[i] = pathSpriteMap[path]; } } } }
public override void OnInspectorGUI() { OnValidateSelected(); var atlas = target as AtlasRaw; EditorGUILayout.GetControlRect(false, 2); int clickIndex = AtlasEditorUtil.TitleBar(new GUIContent[] { new GUIContent("+File"), new GUIContent("+Folder"), }); if (clickIndex == 0) { DisplayImportMenu(atlas, false); } else if (clickIndex == 1) { DisplayImportMenu(atlas, true); } mRepackFold = AtlasEditorUtil.ToggleBar(new GUIContent("Settings"), mRepackFold); if (mRepackFold) { if (!mPackDataInit) { mPackDataInit = true; mSetting = new PackSetting(atlas.maxSize, atlas.padding, atlas.isPOT, atlas.forceSquare); } EditorGUI.indentLevel += 1; mSetting.maxAtlasSize = EditorGUILayout.IntPopup("Max Size", mSetting.maxAtlasSize, Array.ConvertAll(PackConst.AtlasSizeList, value => value.ToString()), PackConst.AtlasSizeList); mSetting.padding = EditorGUILayout.IntField("Padding", mSetting.padding); mSetting.isPOT = EditorGUILayout.Toggle("Power Of 2", mSetting.isPOT); GUI.enabled = mSetting.isPOT; if (!mSetting.isPOT) { mSetting.forceSquare = false; } mSetting.forceSquare = EditorGUILayout.Toggle("Force Square", mSetting.forceSquare); GUI.enabled = true; var rect = EditorGUILayout.GetControlRect(false, 20); if (GUI.Button(new Rect(rect.center.x - 75, rect.y, 150, rect.height), "Repack")) { AtlasPacker.Repack(atlas, null, mSetting); } EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); } EditorGUI.BeginChangeCheck(); mSearchPattern = AtlasEditorUtil.SearchBar(new GUIContent("Search Sprite"), mSearchPattern); if (EditorGUI.EndChangeCheck() || mAtlasDirty) { mSearchResults.Clear(); if (!string.IsNullOrEmpty(mSearchPattern)) { mSearchResults.AddRange(AtlasEditorUtil.SearchSprites(atlas, 0, mSearchPattern)); } } if (mAtlasDirty) { mAtlasDirty = false; mSelectedBin = Mathf.Clamp(mSelectedBin, 0, atlas.bins.Length - 1); mSelectedSprites.Clear(); } EditorGUI.indentLevel += 1; if (!string.IsNullOrEmpty(mSearchPattern)) { EditorGUILayout.LabelField(string.Format("{0} results", mSearchResults.Count)); } if (mSearchResults != null && mSearchResults.Count > 0) { OnValidateResult(); OnSearchResultGUI(); } EditorGUI.indentLevel -= 1; if (atlas.bins.Length > 0) { var titleRect = EditorGUILayout.GetControlRect(false, EditorStyles.toolbar.fixedHeight); var controlId = GUIUtility.GetControlID(FocusType.Passive); var eventType = Event.current.GetTypeForControl(controlId); if (eventType == EventType.Repaint) { EditorStyles.toolbar.Draw(titleRect, GUIContent.none, controlId); } var binNames = Array.ConvertAll(atlas.bins, i => PackUtil.GetDisplayName(i)); var binIndexes = new int[binNames.Length]; for (int i = 0; i < binNames.Length; i++) { binIndexes[i] = i; } mSelectedBin = EditorGUI.IntPopup(new Rect(10, titleRect.y, titleRect.width - 10, titleRect.height), "Preview Bin", mSelectedBin, binNames, binIndexes, EditorStyles.toolbarPopup); mSelectedBin = Mathf.Clamp(mSelectedBin, 0, atlas.bins.Length - 1); EditorGUILayout.Space(); var bin = atlas.bins[mSelectedBin]; var previewRect = EditorGUILayout.GetControlRect(false, 512); previewRect.width = Mathf.Min(previewRect.width, (float)bin.main.width / bin.main.height * previewRect.height); previewRect.height = (float)bin.main.height / bin.main.width * previewRect.width; OnPreviewBin(previewRect); } }
protected virtual BinRaw[] PackSprites(PackSetting setting, IPackSprite[] sprites) { var textures = sprites.Select(sprite => new Packer.Area((int)sprite.rect.width, (int)sprite.rect.height)).ToArray(); var spriteRaws = new List <SpriteRaw>(); var packers = new List <Packer>(); var sizeList = PackConst.AtlasSizeList; var maxSize = setting.maxAtlasSize; var padding = setting.padding; var isPOT = forcePowerOf2 || setting.isPOT; var forceSquare = this.forceSquare || setting.forceSquare; var index = 0; while (index < textures.Length) { var texArea = textures[index]; Packer.Rect texRect = null; for (int i = 0; i < packers.Count; i++) { var packer = packers[i]; while (true) { if (packer.Push(texArea, out texRect)) { spriteRaws.Add(new SpriteRaw() { bin = i, rect = new Rect(texRect.x, texRect.y, texRect.width, texRect.height), }); break; } var width = packer.bin.width; var height = packer.bin.height; if (forceSquare) { width *= 2; height *= 2; } else { if (width > height) { height *= 2; } else { width *= 2; } } if (width > maxSize || height > maxSize) { break; } packer.Extend(new Packer.Bin(width, height)); } if (texRect != null) { break; } } if (texRect == null) { packers.Add(new Packer(Packer.Algorithm.AdvancedHorizontalSkyline, new Packer.Bin(sizeList[0], sizeList[0]), padding)); } else { index += 1; } } var bins = new BinRaw[packers.Count]; for (int i = 0; i < packers.Count; i++) { bins[i] = new BinRaw(); bins[i].size = !isPOT && !forceSquare ? Vector2.zero : new Vector2(packers[i].bin.width, packers[i].bin.height); } if (!isPOT && !forceSquare) { for (int i = 0; i < spriteRaws.Count; i++) { var sprite = spriteRaws[i]; var bin = bins[sprite.bin]; bin.size = new Vector2( Mathf.Max(bin.size.x, sprite.rect.xMax), Mathf.Max(bin.size.y, sprite.rect.yMax)); } if (forceMultiplyOf4) { foreach (var bin in bins) { bin.size = new Vector2( Mathf.CeilToInt(bin.size.x / 4) * 4, Mathf.CeilToInt(bin.size.y / 4) * 4); } } } for (int i = 0; i < sprites.Length; i++) { var sprite = sprites[i]; var spriteRaw = spriteRaws[i]; spriteRaw.name = sprite.name.Replace("\\", "/"); spriteRaw.border = sprite.border; spriteRaw.pivot = sprite.pivot; var rect = spriteRaw.rect; var binRaw = bins[spriteRaw.bin]; binRaw.sprites = binRaw.sprites ?? new SpriteRaw[0]; Array.Resize(ref binRaw.sprites, binRaw.sprites.Length + 1); binRaw.sprites[binRaw.sprites.Length - 1] = spriteRaw; var main = binRaw.main; var add = binRaw.addition; var colors = sprite.Read(); if (main == null) { main = PackUtil.CreateBlankTexture((int)binRaw.size.x, (int)binRaw.size.y, !alphaSplit && transparency ? TextureFormat.RGBA32 : TextureFormat.RGB24); main.hideFlags = HideFlags.DontUnloadUnusedAsset; binRaw.main = main; } main.SetPixels( (int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height, colors); if (alphaSplit && transparency) { if (add == null) { add = PackUtil.CreateBlankTexture((int)binRaw.size.x, (int)binRaw.size.y, TextureFormat.RGB24); add.hideFlags = HideFlags.DontUnloadUnusedAsset; binRaw.addition = add; } for (int c = 0; c < colors.Length; c++) { colors[c] = new Color(colors[c].a, 0, 0); } add.SetPixels( (int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height, colors); } } return(bins); }
public void Setup(PackSetting setting, IPackSprite[] sprites, bool transparency) { mSetting = setting; mSprites = sprites; mTransparency = transparency; }
public static AtlasRaw Repack(AtlasRaw atlasRaw, IPackSprite[] textures = null, PackSetting setting = null) { EditorUtility.DisplayProgressBar("", "repack atlas...", 0.5f); textures = textures ?? PackAtlasSprite.ListSprites(atlasRaw); setting = setting ?? new PackSetting(atlasRaw.maxSize, atlasRaw.padding, atlasRaw.isPOT, atlasRaw.forceSquare); var atlasPath = AssetDatabase.GetAssetPath(atlasRaw); atlasRaw = new PackAtlas(setting, atlasPath, textures).GenerateAtlas(); EditorUtility.ClearProgressBar(); if (atlasRaw == null) { Debug.LogError("Pack failed."); return(null); } RefreshUI(); return(atlasRaw); }