【Unity编辑器扩展】SpriteAltas资源一键转换为TMP_SpriteAsset或Sprite图集

news2024/9/21 2:41:12

【Unity编辑器扩展】艺术字/自定义图片字体/TextMeshPro艺术字生成工具_unity 艺术字-CSDN博客

 博文工具源码见GF_X自动化游戏开发框架:GitHub - sunsvip/GF_X: Unity GameFramework + HybridCLR,Includes several automated editor extension tools, an efficient automated development workflow.(大量自动化编辑器扩展工具, 高效的自动化开发工作流)

 前面博文中介绍过把Sprite图集转换为艺术字的工具,但是通过Unity的Sprite Editor自动划分子Sprite的Rect会有偏差,就需要手动调整Rect,用户体验很差。如果能支持SpriteAtlas,就可以直接把艺术字碎图打成SpriteAtlas,这样就能更好的划分Sprite Rect。

而Text Mesh Pro创建TMP_SpriteAsset资源也很鸡肋(如下图),自己的SpriteAtlas图集功能不用,非要依赖第三方Texture Packer图集。

 

为了解决上述痛点,需要实现两个编辑器扩展功能:

1. 把SpriteAtlas资源直接转换为TMP_SpriteAsset;

2. 把SpriteAtlas资源转换为普通的Sprite图集(Sprite Multiple);

功能实现:

首先通过右键Create->2D->Sprite Atlas创建一个SpriteAtlas资源,然后把碎图拖到SpriteAtlas中:

一,SpriteAtlas转换为TMP_SpriteAsset:

 首先看看TMP_SpriteAsset需要哪些信息:

①. 需要一张图集Texture2D和一个材质;

②. Sprite Character Table,也就是图片映射的字符Unicode、name。TextMeshPro输入字符的Unicode在Sprite Character Table中存在时就会显示对应的Sprite。 而name的作用就是可以通过服富文本标签显示name对应的Sprite:<sprite="sprite_name">

③. Sprite Glyph Table, 也就是Sprite在图集Texture2D中的像素rect区域。

1. SpriteAtlas资源转Texture2D: 

首先要把SpriteAtlas资源生成为一张贴图给TMP_SpriteAsset的材质使用,从SpriteAtlas的Inspector面板可以看到Pack Preview按钮就可以生成图集贴图,所以Unity内部应该是提供了现成接口的。

 通过Unity开源代码就可以快速查到UnityEditor.U2D.SpriteAtlasExtensions有个非公开的静态扩展方法GetPreviewTextures,返回值为Texture2D[],即SpriteAltas每个子图集作为一张Texture。

用法:

var getPreviewFunc = typeof(UnityEditor.U2D.SpriteAtlasExtensions).GetMethod("GetPreviewTextures", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
Texture2D[] previews = getPreviewFunc.Invoke(null, new object[] { atlas }) as Texture2D[];

 但是这里有个问题,通过SpriteAtlasExtensions.GetPreviewTextures拿到的都是压缩过的贴图,并且贴图数据是在一片不可读内存上,不能直接使用EncodeToPNG解码保存为png文件。所以我们需要通过Graphics接口把贴图复制出来:

var atlasTex2d = previews[0];
RenderTexture rt = new RenderTexture(atlasTex2d.width, atlasTex2d.height, 0);
Graphics.Blit(atlasTex2d, rt);
RenderTexture.active = rt;

Texture2D readableAtlasTex = new Texture2D(rt.width, rt.height);
readableAtlasTex.alphaIsTransparency = true;
readableAtlasTex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
readableAtlasTex.Apply();
RenderTexture.active = null;

2. 解析SpriteAltas的碎图并映射到TMP_SpriteAsset的spriteGlyphTable:

Sprite[] sprites = new Sprite[atlas.spriteCount];
atlas.GetSprites(sprites);
TMP_SpriteAsset spriteAsset;
if (File.Exists(tmpSpriteAssetName))
{
    spriteAsset = AssetDatabase.LoadAssetAtPath<TMP_SpriteAsset>(tmpSpriteAssetName);
}
else
{
    spriteAsset = ScriptableObject.CreateInstance<TMP_SpriteAsset>();
    AssetDatabase.CreateAsset(spriteAsset, tmpSpriteAssetName);
}
spriteAsset.spriteSheet = AssetDatabase.LoadAssetAtPath<Texture2D>(textureFileName);
spriteAsset.spriteCharacterTable.Clear();
spriteAsset.spriteGlyphTable.Clear();
if (spriteAsset.material == null)
{
    Material material = new Material(Shader.Find("TextMeshPro/Sprite"));
    material.mainTexture = spriteAsset.spriteSheet;
    AssetDatabase.AddObjectToAsset(material, spriteAsset);
    AssetDatabase.SaveAssetIfDirty(spriteAsset);
    spriteAsset.material = material;
}

for (int i = 0; i < sprites.Length; i++)
{
    var sp = sprites[i];
    var spUVRect = sp.textureRect;
    var glyph = new TMP_SpriteGlyph((uint)i, new UnityEngine.TextCore.GlyphMetrics(spUVRect.width, spUVRect.height, 0, spUVRect.height, spUVRect.width),
    new UnityEngine.TextCore.GlyphRect(spUVRect), 1, 0);
    spriteAsset.spriteGlyphTable.Add(glyph);
    var spChar = new TMP_SpriteCharacter(0xFFFE, glyph);
    spChar.name = sp.name;
    spriteAsset.spriteCharacterTable.Add(spChar);
}
AssetDatabase.SaveAssetIfDirty(spriteAsset);

 SpriteAltas一键转换为TMP_SpriteAsset功能预览:

二, SpriteAltas转换为Sprite Multiple:

也就是通过程序一键把SpriteAltas转换为图集贴图,并自动分割好碎图区域,如下图:

 而我们的艺术字生成工具正好依赖这种分割好的图集,也就间接实现了对碎图的支持,不用依赖Texture Packer等三方图集工具;

功能实现:

前面已经示例了SpriteAltas转为Texture,剩下只需要把Texture类型改成Sprite,Sprite Mode改为Multiple,然后把SpriteAltas碎图Rect映射过来即可:

1. 获取SpriteAtlas所有碎图的Rect信息:

static SpriteRect[] GetSpriteRects(SpriteAtlas atlas)
{
    if (atlas == null || atlas.spriteCount == 0) return null;

    Sprite[] sprites = new Sprite[atlas.spriteCount];
    atlas.GetSprites(sprites);

    SpriteRect[] spriteRects = new SpriteRect[sprites.Length];
    var spNameTrim = "(Clone)".ToCharArray();
    for (int i = 0; i < sprites.Length; i++)
    {
        var sp = sprites[i];
        spriteRects[i] = new SpriteRect()
        {
            name = sp.name.Trim(spNameTrim),
            rect = sp.textureRect
        };
    }
    return spriteRects;
}

2. 根据碎图的Rect信息自动划分:

TextureImporter texImporter = TextureImporter.GetAtPath(textureFileName) as TextureImporter;
var factory = new SpriteDataProviderFactories();
factory.Init();
var dataProvider = factory.GetSpriteEditorDataProviderFromObject(texImporter);
dataProvider.InitSpriteEditorDataProvider();
dataProvider.SetSpriteRects(GetSpriteRects(atlas));
dataProvider.Apply();
texImporter.SaveAndReimport();

 SpriteAltas一键转为Sprite Multiple功能预览:

源码获取:GF_X/Assets/AAAGame/ScriptsBuiltin/Editor/Common/RightClickMemus/RightClickMenuExtension.SpriteAtlasTools.cs at master · sunsvip/GF_X · GitHub 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2097810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue 批量导出pdf 压缩包 zip

vue 批量导出pdf 压缩包 zip 使用插件 html2canvas jspdf jszip &#xff08;百度ai搜出来的是zip-js 这个没法安装&#xff09; file-saver 思路&#xff1a; 1.使用 html2canvasjspdf 将页面转图片转pdf&#xff08;这个怎么转的可以网上搜下很多&#xff09; 2.利用jszipfil…

10个精选ArcGIS图源分享第4辑

数据是GIS的血液。 我们在《10个精选ArcGIS图源分享第3辑》一文中为你分享了10个ArcGIS图源&#xff0c;现在又增加了10个新的图源作为第4辑分享给大家。 并提供了能直接在ArcMap和ArcGIS Pro打开的文件&#xff0c;如果你需要这些ArcGIS图源&#xff0c;请在文末查看该数据的…

iPhone出现4013错误的和解决方案分享

在苹果设备用户群体中&#xff0c;遇到iTunes错误4013是一个颇为棘手的问题。这个错误通常发生在尝试更新iOS系统、恢复iPhone或iPad时&#xff0c;导致操作无法顺利完成。本文将为你提供一系列实用的解决方案&#xff0c;帮助你摆脱iPhone 4013错误的困扰。 一、了解错误4013的…

AI大模型编写多线程并发框架(六十四):监听器优化·下

系列文章目录 文章目录 系列文章目录前言一、项目背景二、第十一轮对话-修正运行时数据三、修正任务计数器四、第十二轮对话-生成单元测试五、验证通过七、参考文章 前言 在这个充满技术创新的时代&#xff0c;AI大模型正成为开发者们的新宠。它们可以帮助我们完成从简单的问答…

面向智能体编程(Agent-Oriented Programming, AOP)

大家已经熟知面向对象编程、面向接口编程&#xff0c;AI大模型研发背景下&#xff0c;又产生了一个新概念&#xff1a;&#xff08;Agent-Oriented Programming, AOP&#xff09; 它是一种特殊的编程范式&#xff0c;它专注于开发能够模拟人类智能行为的智能体。智能体是能够在…

水经微图Web版功能简介

我们在《水经微图Web版341项功能清单》一文中&#xff0c;为你罗列了水经微图&#xff08;下称“微图”&#xff09;的详细功能清单。 现在基于该清单&#xff0c;再为你分享微图最主要的功能&#xff0c;从而让你对该平台有一个基本的了解。 微图Web版功能简介 微图Web版&a…

Vue3 官方推荐状态管理库Pinia

介绍 Pinia 是 Vue 官方团队推荐代替Vuex的一款轻量级状态管理库&#xff0c;允许跨组件/页面共享状态。 Pinia 旨在提供一种更简洁、更直观的方式来处理应用程序的状态。 Pinia 充分利用了 Vue 3 的 Composition API。 官网&#xff1a; Pinia符合直觉的 Vue.js 状态管理库 P…

我如何选择自己的AI细分方向和第一个入门项目

思维导图 下图展示了我的思考和分析过程 目录 思维导图大纲1. **确定兴趣和技能方向**2. **寻找合适的开源项目**3. **评估项目的活跃度**4. **开始贡献**5. **展示你的贡献**6. **推荐开源项目**总结 选择一个细分领域1. **了解各个领域的基本概念**2. **考虑你的兴趣和背景**…

备战秋招60天算法挑战,Day29

题目链接&#xff1a; https://leetcode.cn/problems/decode-ways/ 视频题解&#xff1a; https://www.bilibili.com/video/BV181YKeGE3E/ LeetCode 91. 解码方法 题目描述 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; A -> "1" B -> &qu…

大力出奇迹背景下的Scaling Law能否带领我们走向AGI

Scaling Law&#xff08;尺度定律&#xff09; 在人工智能领域&#xff0c;尤其是在大模型的发展中扮演着至关重要的角色。它描述了模型性能如何随着模型规模&#xff08;如参数数量&#xff09;、数据量和计算资源的增加而提升。这一定律对于理解大模型的能力扩展和优化训练策…

CSS3文本属性详解

4.2 文本属性 想缩进段落&#xff0c;幂指数&#xff0c;标题字符增加间距&#xff0c;要用到文本属性。 最有用的CSS文本属性&#xff1a; text-indent:文本缩进letter-spacing:字符间距word-spacing:单词间距text-decoration:文本装饰&#xff0c;下划线text-align:文字对…

2024年小鹏MONA M03 P7 G3 G3i P5 G9 P7i G6 X9维修手册和电路图

汽修帮手资料库提供各大厂家车型维修手册、电路图、新车特征、车身钣金维修数据、全车拆装、扭力、发动机大修、发动机正时、保养、电路图、针脚定义、模块传感器、保险丝盒图解对照表位置等&#xff0c;并长期保持高频率资料更新&#xff01; 覆盖车型&#xff1a; 2024年小…

langchain结合searXNG实现基于搜索RAG

目录 一、背景 二、环境说明和安装 1.1 环境说明 2.2 环境安装 2.2.1 searXNG安装 三、代码实现 代码 结果输出 直接请求模型输出 四、参考 一、背景 大语言模型的出现带来了新的技术革新&#xff0c;但是大模型由于训练语料的原因&#xff0c;它的知识和当前实时热点…

白酒酿造设备大揭秘:科技与传统的结合

在白酒的酿造世界里&#xff0c;设备与工艺同样重要。它们共同构建了白酒的不同风味和品质。今天&#xff0c;就让我们一起走进豪迈白酒&#xff08;HOMANLISM&#xff09;的酿造车间&#xff0c;探索那些科技与传统相结合的酿造设备&#xff0c;感受它们如何为白酒的酿造增添魅…

Seata环境搭建

1、Seata下载&#xff1a; 1.下载地址 2.下载的版本 2、Seata参数配置参考&#xff1a; 各种seata参数官网参考 3、Seata安装部署&#xff1a; 3.1.Seata新手部署指南: 3.2.在mysql8.0数据库里面建库建表 a.建数据库&#xff1a; create database seata; use seata;b.建…

开源项目管理工具 Plane 安装和使用教程

说到项目管理工具&#xff0c;很多人脑海中第一个蹦出来的可能就是 Jira 了。没错&#xff0c;Jira 确实很强大&#xff0c;但是...它也有点太强大了&#xff0c;既复杂又昂贵&#xff0c;而且目前也不再提供私有化部署版本了。 再说说飞书&#xff0c;作为国产之光&#xff0…

电路基础 ---- 负反馈放大电路的方框图分析法

1 方框图分析法 方框图如下&#xff1a; 图中 A u o A_{uo} Auo​是一个电压输入的放大器的放大倍数&#xff0c;称为开环放大倍数。 F F F为反馈系数&#xff0c;是一个矢量&#xff0c;是指输出信号 x o x_{o} xo​的多少倍回送到放大器的输入端。 M M M为衰减系数&#x…

[pytorch] --- pytorch基础之损失函数与反向传播

1 损失函数 1.1 Loss Function的作用 每次训练神经网络的时候都会有一个目标&#xff0c;也会有一个输出。目标和输出之间的误差&#xff0c;就是用Loss Function来衡量的。所以Loss误差是越小越好的。此外&#xff0c;我们可以根据误差Loss&#xff0c;指导输出output接近目…

浏览器百科:网页存储篇-Cookie详解(一)

1.引言 在现代网页开发中&#xff0c;数据存储和管理是提升用户体验的重要环节之一。作为网页存储技术的元老&#xff0c;Cookie 自从诞生以来就扮演着不可或缺的角色。Cookie 允许网站在用户浏览器中存储小块数据&#xff0c;从而实现状态保持、用户跟踪以及个性化设置等功能…