Sprite Pack打包图集以及获取Sprite

开启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
复制代码

右键菜单就能看到

 

参考

◄ Unity 『功能总结』►——创建ScriptableObject文件/填写/更改变量_臭臭~的博客-CSDN博客

Unity3d Ugui 22图集Sprite Packer_IT界老王的博客-CSDN博客_unity3d 图集

游戏开发unity资源管理系列:SpriteAtlas的Include in Build的作用探究(上)_Cloud Flower的博客-CSDN博客

 

posted @   yanghui01  阅读(1121)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示