首页 > 其他分享 >Unity保存一组sprite为spritesheet

Unity保存一组sprite为spritesheet

时间:2023-09-28 15:36:36浏览次数:41  
标签:sprite filePath System Unity var using spritesheet spriteSheet

背景

之前尝试在Unity编辑器用代码读取打包好的数据,发现在布置场景的时候不能做到所见即所得,这里将运行时读取到的图片素材,保存为spritesheet,并设置对应的sprite。

效果展示

代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.U2D.Sprites;
using UnityEngine;
using static AvatarSpriteGenerate;


#if UNITY_EDITOR

public class SpriteSheet
{
    public List<Sprite> spriteList;
    public string filePath;
}

internal class SpriteSheetToPNG
{

    public static void Save(SpriteSheet spriteSheet)
    {
        var folderPath = Path.GetDirectoryName(spriteSheet.filePath);
        if (!Directory.Exists(folderPath))
            Directory.CreateDirectory(folderPath);

        var rectList = SaveAndGetRect(spriteSheet);
        SetSheet(spriteSheet, rectList);

    }

    private static List<Rect> SaveAndGetRect(SpriteSheet spriteSheet)
    {
        var textureList = new List<Texture2D>();
        foreach (var sprite in spriteSheet.spriteList)
            textureList.Add(sprite.texture);

        Texture2D atlas = new Texture2D(2048, 2048);
        var rects = atlas.PackTextures(textureList.ToArray(), 2, 2048);

        var rectList = new List<Rect>();
        foreach(var rect in rects)
        {
            // PackTextures函数返回的值是相对百分比,需要转化为像素单位
            var xMin = rect.xMin * atlas.width;
            var xMax = rect.xMax * atlas.width;
            var yMin = rect.yMin * atlas.height;
            var yMax = rect.yMax * atlas.height;

            var result = new Rect
            {
                xMin = xMin,
                xMax = xMax,
                yMin = yMin,
                yMax = yMax
            };
            rectList.Add(result);
        }

        byte[] bytes = atlas.EncodeToPNG();
        File.WriteAllBytes(spriteSheet.filePath, bytes);
        var filePath = Path.GetRelativePath(System.Environment.CurrentDirectory, spriteSheet.filePath);
        AssetDatabase.ImportAsset(filePath);
        return rectList;

    }

    private static void SetSheet(SpriteSheet spriteSheet, List<Rect> rectList)
    {
        var filePath = Path.GetRelativePath(System.Environment.CurrentDirectory, spriteSheet.filePath);

        TextureImporter textureImporter = AssetImporter.GetAtPath(filePath) as TextureImporter;
        textureImporter.spriteImportMode = SpriteImportMode.Multiple;
        textureImporter.SaveAndReimport();



        var obj = AssetDatabase.LoadAssetAtPath(filePath, typeof(Texture2D));

        var factory = new SpriteDataProviderFactories();
        factory.Init();
        var dataProvider = factory.GetSpriteEditorDataProviderFromObject(obj);
        dataProvider.InitSpriteEditorDataProvider();

        /* Use the data provider */
        List<SpriteRect> spriteRectList = new List<SpriteRect>();

        for (int i = 0; i < rectList.Count; ++i)
        {
            var rect = rectList[i];
            var sprite = spriteSheet.spriteList[i];

            SpriteRect spriteRect = new SpriteRect();
            spriteRect.rect = rect;
            spriteRect.spriteID = GUID.Generate();
            //sprite.pivot返回的是像素单位,需要转为百分比
            spriteRect.pivot = new Vector2(sprite.pivot.x/ sprite.texture.width, sprite.pivot.y/sprite.texture.height);
            spriteRect.alignment = SpriteAlignment.Custom;
            spriteRect.name = sprite.name;

            spriteRectList.Add(spriteRect);

        }

        dataProvider.SetSpriteRects(spriteRectList.ToArray());
        dataProvider.Apply();

        // Reimport the asset to have the changes applied
        var assetImporter = dataProvider.targetObject as AssetImporter;
        assetImporter.SaveAndReimport();

    }


}

#endif

标签:sprite,filePath,System,Unity,var,using,spritesheet,spriteSheet
From: https://www.cnblogs.com/dewxin/p/17735868.html

相关文章

  • CocosCreator3.x 应用在UI(Sprite)上的 shader 要怎么利用 自定义顶点参数 来实现合批
    前言为啥要合批减少DC什么是自定义顶点参数通过几何体实例化特性(GPUInstancing)可使GPU批量绘制模型相同且材质相同的渲染对象。如果我们想在不打破这一特性的情况下单独修改某个对象的显示效果,就需要通过自定义几何体实例化属性。参考文档UI(Sprite)怎么你了?按照文......
  • Xcode传输包报错Missing signing identifier at UnityFramework.framework/Framewor
    Missingsigningidentifierat"/var/folders/7v/qtz4nc7n4zv025173khwftsm0000gn/T/XcodeDistPipeline.~~~7SDZNJ/Root/Payload/SJSD.app/Frameworks/UnityFramework.framework/Frameworks/libswiftCore.dylib".ios集成unity项目传包报错:删除Frameworks/UnityFramework.......
  • UnityGLTF插件加载模型时,emissiveFactor解析报错
    项目中遇到使用 UnityGLTF插件加载GLTF模型时报错,如下图: 根据报错信息,我们找到GLTF文件中,第[五]个材质的描述:{"name":"11_-_Default木质长廊1.bmp_alpha","occlusionTexture":{"index":0,"texCoord":1},......
  • unity 框选物体实现
    1.效果图 2.里面包含两个完整项目,都能实现效果(unity版本2021.3.4)下载地址 没有积分的可以私聊我,发我邮箱,看到会发送的(一般工作日很快) ......
  • UnityGLTF插件加载模型时,OcclusionTexture贴图显示错误的问题处理
    工作中遇到使用UnityGLTF插件加载GLTF模型时,贴图显示错误的问题,如下图 检查材质时发现,把OcclusionTexture去掉就看起来正常了  看来是插件对OcclusionTexture的解析出了问题, 那么我们来看一下,GLTF中对OcclusionTexture的描述片段,是这样:"name":"5木质长廊1.bmp","o......
  • (十五)Unity性能优化-Stats(统计数据窗口)
    通过Stats窗口可以初步查看游戏运行时,当前一帧的各项性能。Stats是英文单词Statistics的缩写,意思是“统计数据”。打开方法:Game窗口右上角,找到Stats,点击它。Audio表示音频的数据Level表示声音强度,单位是分贝,也就是dB。声音太大或太小都会影响玩家体验。应将这项数据......
  • (十四)Unity性能优化-常见问题
    Unity下常见的等待函数WaitForTargetFPS:等待达到目标帧率,一般这种情况CPU与GPU都没什么负载问题Gfx.WaitForGfxCommandsFromMainThread/WaitForCommand:渲染线程已经准备接受新的渲染命令,一般瓶颈在CPUGfx.WaitForPresentOnGfxThread/WaitForPresent:主线程等待渲染线程绘制完成......
  • Measuring Node Contribution to Community Structure With Modularity Vitality
    MeasuringNodeContributiontoCommunityStructureWithModularityVitality用模块性生命力度量节点对社区结构的贡献摘要社区感知中心性是网络科学中一个新兴的研究领域,关注节点在社区结构中的重要性。先前的方法扩展了经典的中心性度量来解释社区结构,而与社区检测理论几......
  • unitycn.cn 关停了
    用了好几年的域名unitycn.cn,UnityHome,由于云服务提供商CloudLeft停止这块业务了,所以我也不打算再去找其他的替代了。用成熟的网站代替自己搭站。日后的技术文章,就在新浪微博、csdn、博客园、简书、51CTO、zhihu这些平台发表吧。--2023年9月26日......
  • 唐老狮Unity基础笔记
    唐老狮Unity基础笔记三角函数Mathf.Rad2DegMathf.Deg2Rad 坐标系 向量    ......