首页 > 其他分享 >Sprite Pack打包图集以及获取Sprite

Sprite Pack打包图集以及获取Sprite

时间:2022-11-21 01:00:20浏览次数:59  
标签:return Sprite Debug var using 图集 Pack

开启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

相关文章

  • Keil Pack Installer 连接超时的解决办法
    KeilPackInstaller连接超时的解决办法国内访问Keil网站实在不靠谱,用PackInstaller更新或安装Pack经常超时。幸运的是PackInstaller支持安装本地Pack,因此可以使用下载工......
  • webpack热加载等一些常用配置
    1、查看webpack打包文件以及对应信息webpack--display-modules--display-reasons2、webpack-p:会对文件进行优化,压缩等3、webpack-d:对应配置文件的devtool4、webpack......
  • Vue中使用Mock,devSever中before方法弃用>webpack新版本出现的vue.config.js配置问题:op
    话不多说直接上代码:1、mock相关配置(mock/index.js),这里仅使用 setupMiddlewares其余旧版级过渡版本方法见官网1//引入mock2constMock=require('mockjs');......
  • 深度解读Webpack中的loader原理
    一、前言webpack是一个现代JavaScript应用的静态模块打包器。那么webpack是怎样实现不同种类资源模块加载的呢?没错就是通过loader。loader用于对模块的源代码进行......
  • Webpack中的plugin插件机制
    大家有没有遇到过这些问题:webpack打包之后的文件没有压缩静态文件要手动拷贝到输出目录代码中写了很多环境判断的多余代码上一篇「webpack核心特性」loader说到......
  • 详解webpack构建优化
    当项目越来越复杂时,会面临着构建速度慢和构建出来的文件体积大的问题。webapck构建优化对于大项目是必须要考虑的一件事,下面我们就从速度和体积两方面来探讨构建优化的策略......
  • 自学 TypeScript 第三天 使用webpack打包 TS 代码
    前言:大家好啊,昨天介绍了TS编译器的配置,但在我们实际开发当中直接使用TS编译器去编译代码的情况会有,但没有很多,因为我们在开发大型项目的时候,一般我们都会用到打包工具......
  • 你需要知道的webpack高频面试题
    谈谈你对webpack的看法webpack是一个模块打包工具,可以使用它管理项目中的模块依赖,并编译输出模块所需的静态文件。它可以很好地管理、打包开发中所用到的HTML,CSS,JavaScr......
  • 教你手写webpack常用loader
    前言webpack作为目前主流的前端构建工具,我们几乎每天都需要与它打交道。个人认为一个好的开源产品壮大的原因应该包括核心开发者的稳定输出以及对应生态的繁荣。对于生态......
  • how to install python package? _ ModuleNotFoundError:
     #......