TextMeshPro编辑器扩展,文字样式预设

在游戏开发过程中,美术一般对游戏内的文字有一套规范,如:

  • 标题1 字体xx 字号30 字色#00FF00 材质xx
  • 标题2 字体xx 字号35 字色#00FFFF 材质xx
  • 文本1 字体xx 字号25 字色#00FFFF 材质xx

为了提升拼界面的效率,减少手动设置的错误,可以对TextMeshPro进行扩展,添加下拉列表来快速选择样式,先看效果。
在这里插入图片描述
代码中使用了Odin插件的功能,对Odin不了解的可以先看下Odin入门

首先在Editor目录下新建文件夹TMP_Preset,相关代码都放入这里,新建下列脚本
TMP_Preset脚本用于定义一些参数

using System;
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using TMPro;
using TMPro.EditorUtilities;
using UnityEngine;

[CreateAssetMenu(menuName = "文字预设")]
public class TMP_Preset : ScriptableObject
{
    
    
    public List<TMP_Style> styles = new List<TMP_Style>();
}

[Serializable]
public class TMP_Style
{
    
    
    [HorizontalGroup("Split"), HideLabel]
    public string Name;

    [HorizontalGroup("Split", 200), HideLabel]
    public TMP_FontAsset FontAsset;

    [Range(1,99)]
    [LabelText("字号")]
    [HorizontalGroup("Split", LabelWidth = 30)]
    public int FontSize;

    [HorizontalGroup("Split", 40), HideLabel]
    public Color Color = Color.white;
    
    [HorizontalGroup("Split", 200), HideLabel]
    [ValueDropdown("GetAllMaterialName")]
    public int MaterialIndex;
    
    [HorizontalGroup("Split"), HideLabel]
    [ValueDropdown("ColorMode")]
    public int GradientMode;
    
    [HorizontalGroup("Split", 40), HideLabel]
    [BoxGroup("Split/Left")]
    [ShowIf("@this.GradientMode > 0")]
    [OnValueChanged("OnGradientModeChanged")]
    public Color topLeft = Color.white;
    
    [HorizontalGroup("Split", 40), HideLabel]
    [BoxGroup("Split/Left")]
    [ShowIf("@this.GradientMode == 2 || this.GradientMode == 3")]
    [OnValueChanged("OnGradientModeChanged")]
    public Color bottomLeft = Color.white;
    
    [HorizontalGroup("Split", 40), HideLabel]
    [BoxGroup("Split/Right")]
    [ShowIf("@this.GradientMode == 1 || this.GradientMode == 3")]
    [OnValueChanged("OnGradientModeChanged")]
    public Color topRight = Color.white;
    
    [HorizontalGroup("Split", 40), HideLabel]
    [BoxGroup("Split/Right")]
    [ShowIf("@this.GradientMode == 3")]
    public Color bottomRight = Color.white;
    
    private ValueDropdownList<int> materialNames = new ValueDropdownList<int>();
    private static IEnumerable ColorMode = new ValueDropdownList<int>()
    {
    
    
        {
    
     "无渐变", 0 },
        {
    
     "水平渐变", 1 },
        {
    
     "垂直渐变", 2 },
        {
    
     "四角渐变", 3 },
    };
    
    private IEnumerable GetAllMaterialName()
    {
    
    
        materialNames.Clear();
        if (FontAsset != null)
        {
    
    
            var materials = TMP_EditorUtility.FindMaterialReferences(FontAsset);
            for (int i = 0; i < materials.Length; ++i)
            {
    
    
                materialNames.Add(materials[i].name, i);
            }
        }
        
        return materialNames;
    }

    private void OnGradientModeChanged()
    {
    
    
        switch (GradientMode)
        {
    
    
            case (int)TMPro.ColorMode.HorizontalGradient:
                bottomLeft = topLeft;
                bottomRight = topRight;
                break;
            case (int)TMPro.ColorMode.VerticalGradient:
                topRight = topLeft;
                bottomRight = bottomLeft;
                break;
        }
    }
}

TMP_EditorWindow 用于添加编辑预设

using System;
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using UnityEditor;
using UnityEngine;

public class TMP_EditorWindow : OdinEditorWindow
{
    
    
    [MenuItem("工具箱/文字预设", priority = 1)]
    private static void OpenWindow()
    {
    
    
        var window = GetWindow<TMP_EditorWindow>();
        window.position = GUIHelper.GetEditorWindowRect().AlignCenter(900, 700);
    }

    public TMP_Preset config;
    
    [Space(20)]
    [ListDrawerSettings(AddCopiesLastElement = true, NumberOfItemsPerPage = 30)]
    [OnValueChanged("SaveData")]
    public List<TMP_Style> styles = new List<TMP_Style>();
    
    public const string Path = "Assets/Editor/TMP_Preset/TMP_Preset.asset";


    [OnInspectorInit]
    private void OnInit()
    {
    
    
        config = (TMP_Preset)AssetDatabase.LoadAssetAtPath(Path, typeof(TMP_Preset));
        if (config == null)
            return;
        
        styles.Clear();
        styles.AddRange(config.styles);
    }

    /// <summary>
    /// 保存数据
    /// </summary>
    [OnInspectorDispose]
    private void SaveData()
    {
    
    
        if (config == null)
            return;
        
        config.styles.Clear();
        config.styles.AddRange(styles);
        EditorUtility.SetDirty(config);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
}

TMP_CustomEditorPanel 用于扩展TMP面板

using System.Collections.Generic;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using UnityEditor;
using UnityEngine;

namespace TMPro.EditorUtilities
{
    
    
    [CustomEditor(typeof(TextMeshProUGUI), true), CanEditMultipleObjects]
    public class TMP_CustomEditorPanel : TMP_EditorPanelUI
    {
    
    
        private int _styleIndex;
        private string[] _styleNames = new string[0];
        private TMP_Preset _tmpPreset;

        protected override void OnEnable()
        {
    
    
            base.OnEnable();
            _tmpPreset = (TMP_Preset)AssetDatabase.LoadAssetAtPath(TMP_EditorWindow.Path, typeof(TMP_Preset));
            if (_tmpPreset == null)
                return;
            
            _styleNames = new string[_tmpPreset.styles.Count + 1];
            _styleNames[0] = "None";
            for (int i = 0; i < _tmpPreset.styles.Count; ++i)
            {
    
    
                _styleNames[i + 1] = _tmpPreset.styles[i].Name;
            }
        }

        public override void OnInspectorGUI()
        {
    
    
            EditorGUILayout.BeginHorizontal();
            {
    
    
                //显示下拉列表
                _styleIndex = EditorGUILayout.Popup("样式", _styleIndex, _styleNames);
                for (int i = 0; i < targets.Length; ++i)
                {
    
    
                    var tmp = targets[i] as TextMeshProUGUI;
                    if (_styleIndex > 0 && _tmpPreset != null)
                    {
    
    
                        var style = _tmpPreset.styles[_styleIndex - 1];
                        tmp.font = style.FontAsset;
                        tmp.fontSize = style.FontSize;
                        tmp.color = style.Color;
                        tmp.horizontalMapping = TextureMappingOptions.Line;
                        tmp.verticalMapping = TextureMappingOptions.Line;
                        var materials = TMP_EditorUtility.FindMaterialReferences(style.FontAsset);
                        tmp.fontSharedMaterial = materials[style.MaterialIndex];
                            
                        switch (style.GradientMode)
                        {
    
    
                            case 0: //无渐变
                                tmp.enableVertexGradient = false;
                                break;
                            case (int)ColorMode.HorizontalGradient:  //水平渐变
                            case (int)ColorMode.VerticalGradient:    //竖直渐变
                            case (int)ColorMode.FourCornersGradient: //四角渐变
                                tmp.enableVertexGradient = true;
                                var colorMode = serializedObject.FindProperty("m_colorMode");
                                colorMode.enumValueIndex = style.GradientMode;
                                serializedObject.ApplyModifiedProperties();
                                tmp.colorGradient = new VertexGradient(style.topLeft, style.topRight,
                                    style.bottomLeft, style.bottomRight);
                                break;
                        }
                    }
                }

                if (GUILayout.Button("编辑", GUILayout.Width(100)))
                {
    
    
                    var window = EditorWindow.GetWindow<TMP_EditorWindow>();
                    window.position = GUIHelper.GetEditorWindowRect().AlignCenter(900, 700);
                }
            }
            EditorGUILayout.EndHorizontal();
        
            base.OnInspectorGUI();
        }
    }
}

在文件夹下右键选择文字预设,添加TMP_Preset.asset文件用于保存预设信息。
在这里插入图片描述
在这里插入图片描述
点击工具箱-文字预设,打开编辑窗口,点击+添加样式,这里就是把美术给的规范添加上,然后就可以在TMP面板上下拉列表中选择了,如果下拉列表中没有显示,先点击其他空白出,再点击文本刷新下界面。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sinat_34014668/article/details/126448044