当前位置: 首页 > article >正文

TextMeshPro保存偏移数据

TextMeshPro保存偏移数据

    • 需求
    • 保存
    • 读取
    • 完整代码

需求

使用TextMeshPro的图文混排,图片位置和文字有偏移,常需要使用以下属性调整图片的偏移数据

但是图集扩展时,重新打包图集,这个数据常被覆盖掉。策划想要个小工具处理一下,代替每次都手填。

保存

用脚本编辑器打开图文混排的图集,查看数据

数据结构很简单,很容易发现上图m_SpriteGlyphTable下的m_HorizontalBearingXm_HorizontalBearingY就是我们需要的偏移数据。
这里我准备使用一个Json文件把他保存到本地,生成新的图集文件后,再导入存储的数据。

m_SpriteGlyphTable数据只有index,没有图片名。新增图片后,index可能变更。如上图,图片名在m_SpriteCharacterTablem_Name属性

 [MenuItem(MenuItemText, false, 25)]
    public static void SaveData()
    {
        //判断路径Assets/Tools 是否有对应json文件
        var path = AssetDatabase.GetAssetPath(Selection.activeObject);
        var jsonPath = $"Assets/Tools/{Selection.activeObject.name}.json";
        if (!File.Exists(jsonPath))
        {
            File.Create(jsonPath).Dispose();
        }
        var tmpSpriteAsset = AssetDatabase.LoadAssetAtPath<TMP_SpriteAsset>(path);
        var list = tmpSpriteAsset.spriteGlyphTable;
        var dic = new Dictionary<string, List<float>>();
        for (var i = 0; i < list.Count; i++)
        {
            var data = new List<float>();
            var spriteGlyph = list[i];
            var metrics = spriteGlyph.metrics;
            data.Add(metrics.horizontalBearingX);
            data.Add(metrics.horizontalBearingY);
            var name = tmpSpriteAsset.spriteCharacterTable[(int)spriteGlyph.index].name ;
            dic.Add(name, data);
        }
        var str = JsonConvert.SerializeObject(dic);
        File.WriteAllText(jsonPath,str);
        AssetDatabase.Refresh();
    }

以上完成保存图集

读取

修改图集后,可以读取导入存储的偏移数据

 [MenuItem(MenuItemText1, false, 25)]
    public static void ReadData()
    {
        var path = AssetDatabase.GetAssetPath(Selection.activeObject);
        //这里填自己缓存json文件的路径
        var jsonPath = $"Assets/Tools/{Selection.activeObject.name}.json";
        if (!File.Exists(jsonPath))
        {
            Debug.LogError("没有对应的预存json文件");
            return;
        }
        var json = File.ReadAllText(jsonPath);
        var dic = JsonConvert.DeserializeObject<Dictionary<string, List<float>>>(json);
        var tmpSpriteAsset = AssetDatabase.LoadAssetAtPath<TMP_SpriteAsset>(path);
        for (var i = 0; i < tmpSpriteAsset.spriteGlyphTable.Count; i++)
        {
            var spriteGlyph = tmpSpriteAsset.spriteGlyphTable[i];
            var name = tmpSpriteAsset.spriteCharacterTable[(int)spriteGlyph.index].name;
            if (dic.ContainsKey(name))
            {
                var data = dic[name];
                var metrics = spriteGlyph.metrics;
                metrics.horizontalBearingX = data[0];
                metrics.horizontalBearingY = data[1];
                spriteGlyph.metrics = metrics;
            }
        }
        EditorUtility.SetDirty(tmpSpriteAsset);
        AssetDatabase.SaveAssets();
    }

完整代码

using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using TMPro;
using UnityEditor;
using UnityEngine;
public class TmpCustomEditors 
{
    private const string MenuItemText = "Assets/工具/Tmp保存偏移数据";
    private const string MenuItemText1 = "Assets/工具/Tmp导入偏移数据";
        
 
    [MenuItem(MenuItemText, false, 25)]
    public static void SaveData()
    {
        //判断路径Assets/Tools 是否有对应json文件
        var path = AssetDatabase.GetAssetPath(Selection.activeObject);
        var jsonPath = $"Assets/Tools/{Selection.activeObject.name}.json";
        if (!File.Exists(jsonPath))
        {
            File.Create(jsonPath).Dispose();
        }
        var tmpSpriteAsset = AssetDatabase.LoadAssetAtPath<TMP_SpriteAsset>(path);
        var list = tmpSpriteAsset.spriteGlyphTable;
        var dic = new Dictionary<string, List<float>>();
        for (var i = 0; i < list.Count; i++)
        {
            var data = new List<float>();
            var spriteGlyph = list[i];
            var metrics = spriteGlyph.metrics;
            data.Add(metrics.horizontalBearingX);
            data.Add(metrics.horizontalBearingY);
            var name = tmpSpriteAsset.spriteCharacterTable[(int)spriteGlyph.index].name ;
            dic.Add(name, data);
        }
        var str = JsonConvert.SerializeObject(dic);
        File.WriteAllText(jsonPath,str);
        AssetDatabase.Refresh();
    }
    
    [MenuItem(MenuItemText, true)]
    public static bool Validate()
    {
        if (!Selection.activeObject) return false;
        var path = AssetDatabase.GetAssetPath(Selection.activeObject);
        return IsTmpSpriteFile(path);

    }
    [MenuItem(MenuItemText1, false, 25)]
    public static void ReadData()
    {
        var path = AssetDatabase.GetAssetPath(Selection.activeObject);
        //这里填自己缓存json文件的路径
        var jsonPath = $"Assets/Tools/{Selection.activeObject.name}.json";
        if (!File.Exists(jsonPath))
        {
            Debug.LogError("没有对应的预存json文件");
            return;
        }
        var json = File.ReadAllText(jsonPath);
        var dic = JsonConvert.DeserializeObject<Dictionary<string, List<float>>>(json);
        var tmpSpriteAsset = AssetDatabase.LoadAssetAtPath<TMP_SpriteAsset>(path);
        for (var i = 0; i < tmpSpriteAsset.spriteGlyphTable.Count; i++)
        {
            var spriteGlyph = tmpSpriteAsset.spriteGlyphTable[i];
            var name = tmpSpriteAsset.spriteCharacterTable[(int)spriteGlyph.index].name;
            if (dic.ContainsKey(name))
            {
                var data = dic[name];
                var metrics = spriteGlyph.metrics;
                metrics.horizontalBearingX = data[0];
                metrics.horizontalBearingY = data[1];
                spriteGlyph.metrics = metrics;
            }
        }
        EditorUtility.SetDirty(tmpSpriteAsset);
        AssetDatabase.SaveAssets();
    }
    [MenuItem(MenuItemText1, true)]
    public static bool Validate1()
    {
        if (!Selection.activeObject) return false;
        var path = AssetDatabase.GetAssetPath(Selection.activeObject);
        return IsTmpSpriteFile(path);

    }
    private static bool IsTmpSpriteFile(string path)
    {
        //判断是否是TMP_SpriteAsset文件,路径自定义
        return path.StartsWith("Assets/ThirdParty/TextMesh Pro/Resources/Sprite Assets");
    }
}



http://www.kler.cn/a/471163.html

相关文章:

  • LabVIEW之树形控件
  • 自动采集商品信息、处理数据并自动上架到
  • 国产编辑器EverEdit - 两种删除空白行的方法
  • Linux之信号量
  • 小结:DNS,HTTP,SMTP,IMAP,FTP,Telnet,TCP,ARP,ICMP
  • 第431场周赛:最长乘积等价子数组、计算字符串的镜像分数、收集连续 K 个袋子可以获得的最多硬币数量、不重叠区间的最大得分
  • React18实现账单管理项目(三):日期分组与图标适配
  • 请求是如何通过k8s service 路由到对应的pod
  • Express 加 sqlite3 写一个简单博客
  • Oracle SQL子查询实例
  • UE4_用户控件_4_Widgets嵌套Widgets构建复杂系统
  • VLMs之Agent之CogAgent:CogAgent的简介、安装和使用方法、案例应用之详细攻略
  • Yolov8训练方式以及C#中读取yolov8+onnx模型进行目标检测.NET 6.0
  • 分布式与集群
  • 基于SpringBoot+Vue的考研百科网站
  • UG NX二次开发(C++)-UFun函数-按照特定方向提取轮廓线
  • el-table拖拽表格
  • 吉客云与金蝶云星空数据集成技术详解
  • 20250107在WIN10下使用无线ADB连接Andorid7.1.2
  • vulnhub whowantstobeking靶机
  • C++中,typename
  • 初学stm32 --- 电源监控
  • 数据库6讲
  • 基于GUI网络渗透侦察工具设计与实践
  • PCL 点云多边形面积计算
  • 寒假刷题Day1