在游戏开发过程中,美术一般对游戏内的文字有一套规范,如:
- 标题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面板上下拉列表中选择了,如果下拉列表中没有显示,先点击其他空白出,再点击文本刷新下界面。