开启Sprite Pack
图集打包
Packing Tag设置成相同名字的图片就会被打包进同一个图集
a) 图集common_ui
b) 图集icon
查看图集
菜单 -> Window -> 2D -> Sprite Packer
获取图集中的Sprite
Sprite Pack打包的图集,Unity并没有给我们提供api来获取单个Sprite,只能通过先在编辑器中将Sprite绑定到脚本上的方式来获取。
1) 这边通过自定义Asset的方式来绑定Sprite
using System.Collections.Generic; using UnityEngine; [CreateAssetMenu] public class Atlas : ScriptableObject { public List<Sprite> spriteList = new List<Sprite>(); private Dictionary<string, Sprite> _spriteDict; public Sprite this[string name] { get { return GetSprite(name); } } public Sprite GetSprite(string spriteName) { if (null == _spriteDict) { _spriteDict = new Dictionary<string, Sprite>(); foreach (var sprite in spriteList) _spriteDict[sprite.name] = sprite; } if (!_spriteDict.TryGetValue(spriteName, out var sp)) Debug.LogError($"sprite not found: {spriteName} in atlas: {name}"); return sp; } }
2) 然后我们可以右键创建一个Atlas自定义资源
3) 然后我们可以选中新建的Atlas资源,然后将Sprite一个一个绑定到spriteList这个列表上
4) 在代码中使用
#if UNITY_EDITOR using UnityEditor; using UnityEngine; using UnityEngine.UI; public class AtlasUseDemo : MonoBehaviour { void Start() { //正式代码使用AssetBundle的方式来加载, 这边只是Demo直接用了UnityEditor的api来加载 var atlas = AssetDatabase.LoadAssetAtPath<Atlas>("Assets/Atlas/Atlas_ui/New Atlas.asset"); if (null == atlas) { Debug.Log($"atlas null"); return; } var img = GetComponent<Image>(); img.sprite = atlas.GetSprite("btn_back"); img.SetNativeSize(); } } #endif
一开始Image没有图片
运行起来后图片被设为btn_back
Atlas小工具
1) 自动把文件夹下的所有Sprite绑定到spriteList上
#if UNITY_EDITOR using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; public class AtlasInitTool { [MenuItem("CONTEXT/Atlas/使用当前文件夹下的所有Sprite初始化")] static void InitSpriteList(MenuCommand menuCMD) { var assetPath = AssetDatabase.GetAssetPath(menuCMD.context); if (string.IsNullOrEmpty(assetPath)) return; Debug.Log($"{assetPath}"); var atlas = menuCMD.context as Atlas; if (null == atlas) return; var dirPath = Path.GetDirectoryName(assetPath); //Debug.Log($"dir: {dirPath}"); //文件夹下的所有Sprite添加到atlas下 var spriteList = new List<Sprite>(); FindAndAddSprite(spriteList, dirPath, "*.png"); FindAndAddSprite(spriteList, dirPath, "*.jpg"); FindAndAddSprite(spriteList, dirPath, "*.jpeg"); atlas.spriteList = spriteList; EditorUtility.SetDirty(atlas); Debug.Log($"finish"); } private static void FindAndAddSprite(List<Sprite> spriteList, string dirPath, string pattern) { var files = Directory.GetFiles(dirPath, pattern, SearchOption.TopDirectoryOnly); if (null == files || files.Length <= 0) return; //Debug.Log($"{dirPath}, {pattern}, {files.Length}"); for (var i = 0; i < files.Length; ++i) { //Debug.Log($"sprite file: {files[i]}"); var arr = AssetDatabase.LoadAllAssetsAtPath(files[i]); if (null != arr) { for (var j = 0; j < arr.Length; ++j) { var sprite = arr[j] as Sprite; if (null != sprite) { spriteList.Add(sprite); } } } } } } #endif
右键菜单就能看到
2) 导出图集工具,Unity只提供了预览工具,没法拿到图集图片
#if UNITY_EDITOR using UnityEditor; using UnityEditor.Sprites; using UnityEngine; using System.IO; public class AtlasExportTool { [MenuItem("MyTools/PackSpritesAndExportSelectAtlas", true)] static bool PackSpritesAndExportSelectAtlasValidate() { return null != Selection.activeObject; } [MenuItem("MyTools/PackSpritesAndExportSelectAtlas")] static void PackSpritesAndExportSelectAtlas() { if (null == Selection.activeObject) return; if (Application.isPlaying) return; var assetPath = AssetDatabase.GetAssetPath(Selection.activeObject); var imp = AssetImporter.GetAtPath(assetPath) as TextureImporter; if (null == imp || TextureImporterType.Sprite != imp.textureType) { Debug.Log($"所选资源不是Sprite"); return; } if (string.IsNullOrEmpty(imp.spritePackingTag)) { Debug.Log($"所选Sprite没有Packting Tag"); return; } string outDirPath = "_AtlasTemp"; if (!Directory.Exists(outDirPath)) { Directory.CreateDirectory(outDirPath); } EditorUtility.DisplayProgressBar("RebuildAtlasCacheIfNeeded...", "RebuildAtlasCacheIfNeeded...", 0); Packer.RebuildAtlasCacheIfNeeded(EditorUserBuildSettings.activeBuildTarget, true, Packer.Execution.ForceRegroup); EditorUtility.ClearProgressBar(); Debug.Log($"atlasName: {imp.spritePackingTag}"); var textures = Packer.GetTexturesForAtlas(imp.spritePackingTag); ExportTextures(outDirPath, textures); Debug.Log($"finish"); } [MenuItem("MyTools/PackSpritesAndExportAtlas")] static void PackSpritesAndExportAtlas() { if (Application.isPlaying) return; string outDirPath = "_AtlasTemp"; if (!Directory.Exists(outDirPath)) { Directory.CreateDirectory(outDirPath); } EditorUtility.DisplayProgressBar("RebuildAtlasCacheIfNeeded...", "RebuildAtlasCacheIfNeeded...", 0); Packer.RebuildAtlasCacheIfNeeded(EditorUserBuildSettings.activeBuildTarget, true, Packer.Execution.ForceRegroup); EditorUtility.ClearProgressBar(); foreach (var atlasName in Packer.atlasNames) { Debug.Log($"atlasName: {atlasName}"); var textures = Packer.GetTexturesForAtlas(atlasName); ExportTextures(outDirPath, textures); } Debug.Log($"finish"); } static void ExportTextures(string outDirPath, Texture[] textures) { for (int i = 0; i < textures.Length; i++) { var tex = textures[i]; var tempRT = RenderTexture.GetTemporary(tex.width, tex.height, 0, RenderTextureFormat.ARGB32); Graphics.SetRenderTarget(tempRT); Graphics.Blit(tex, tempRT); var resultTex = new Texture2D(tex.width, tex.height, TextureFormat.RGBA32, false); resultTex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0); resultTex.Apply(); var bytes = resultTex.EncodeToPNG(); Graphics.SetRenderTarget(null); RenderTexture.ReleaseTemporary(tempRT); //var bytes = tex.EncodeToPNG(); var resultFilePath = ""; if (1 == textures.Length) resultFilePath = Path.Combine(outDirPath, $"{tex.name}.png"); else resultFilePath = Path.Combine(outDirPath, $"{tex.name}-Page{i}.png"); File.WriteAllBytes(resultFilePath, bytes); } } } #endif
导出的图集
参考
◄ Unity 『功能总结』►——创建ScriptableObject文件/填写/更改变量_臭臭~的博客-CSDN博客
Unity3d Ugui 22图集Sprite Packer_IT界老王的博客-CSDN博客_unity3d 图集
游戏开发unity资源管理系列:SpriteAtlas的Include in Build的作用探究(上)_Cloud Flower的博客-CSDN博客
标签:return,Sprite,Debug,var,using,图集,Pack From: https://www.cnblogs.com/sailJs/p/16477766.html