目录
本文内容效果工具代码制作美术字体1 资源1.1 资源方式1.2 资源命名1.3 资源命名配置
2 打包字体2.1 创建字体2.2 更新字体
3 字体使用
本文内容
开发过程有个很常见的需求:使用美术提供的图片来表现美术字体。
Unity官方为此提供了一个自定义字体,用于在UI上显示图片字体,具体各参数意义可以参考https://docs.unity3d.com/2022.2/Documentation/Manual/class-Font.html。 ![请添加图片描述](https://img-blog.csdnimg.cn/3b43462949fd4c0793abd9a775d763dc.png)
效果
如下,我们可以很自由的展示图片字体。 ![请添加图片描述](https://img-blog.csdnimg.cn/56cf492f18d34c6287a3495af395c2ba.png)
工具代码
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
public class CrisFontWindow: EditorWindow
{
private string fontPath = "Assets/crisFont.fontsettings";
private Font font;
private Rect[] rects;
private TextAsset characterCfg;
void OnGUI()
{
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.Label("字体:", GUILayout.Width(100.0f));
font = (Font)EditorGUILayout.ObjectField(font, typeof(Font), true);
GUILayout.EndHorizontal();
if (font == null)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Label("字体路径", GUILayout.Width(100));
fontPath = GUILayout.TextField(fontPath);
EditorGUILayout.EndHorizontal();
if (GUILayout.Button("新建字体"))
{
Font newFont = new Font();
try
{
AssetDatabase.CreateAsset(newFont, fontPath);
font = AssetDatabase.LoadAssetAtPath(fontPath);
}
catch
{
}
if (font == null) Debug.LogError("路径错误:" + fontPath);
}
}
else
{
GUILayout.BeginHorizontal();
GUILayout.Label("字体配置:", GUILayout.Width(100.0f));
characterCfg = (TextAsset)EditorGUILayout.ObjectField(characterCfg, typeof(TextAsset), true);
GUILayout.EndHorizontal();
GUILayout.Label("请选中需要打入的字体文件");
GUILayout.BeginHorizontal();
if (GUILayout.Button("更新文本")) UpdateFont();
GUILayout.EndHorizontal();
}
GUILayout.EndVertical();
}
void UpdateFont()
{
string fontPath = AssetDatabase.GetAssetPath(font);
string fontDir = Path.GetDirectoryName(fontPath);
var texSavePath = Path.Combine(fontDir, Path.GetFileNameWithoutExtension(fontPath) + ".png");
CombineTexture(texSavePath);
var tex = AssetDatabase.LoadAssetAtPath(texSavePath);
if (tex == null) Debug.LogError("未发现生成的图集");
var matPath = Path.Combine(fontDir, Path.GetFileNameWithoutExtension(fontPath) + ".mat");
var mat = AssetDatabase.LoadAssetAtPath(matPath);
if (mat == null)
{
var newMat = new Material(Shader.Find("GUI/Text Shader"));
AssetDatabase.CreateAsset(newMat, matPath);
mat = newMat;
}
mat.SetTexture("_MainTex", tex);
EditorUtility.SetDirty(mat);
var list = new List();
float maxHeight = 0;
for (int i = 0; i < rects.Length; i++)
{
if (rects[i].height > maxHeight) maxHeight = rects[i].height;
}
for (int i = 0; i < rects.Length; i++)
{
Rect rect = ConvertToPixels(rects[i], tex.width, tex.height);
int asciiIndex = ac[i];
var charInfo = new CharacterInfo();
charInfo.index = asciiIndex;
Rect uv = ConvertToTexCoords(rect, tex.width, tex.height);
charInfo.uvBottomLeft = new Vector2(uv.x, uv.y);
charInfo.uvTopLeft = new Vector2(uv.x, uv.y + uv.height);
charInfo.uvBottomRight = new Vector2(uv.x + uv.width, uv.y);
charInfo.uvTopRight = new Vector2(uv.x + uv.width, uv.y + uv.height);
charInfo.minX = 0;
charInfo.maxX = (int)rect.width;
charInfo.minY = (int)(tex.height / 2 - (maxHeight - rect.height) / 2 - rect.height);
charInfo.maxY = (int)(tex.height / 2 - (maxHeight - rect.height) / 2);
charInfo.advance = (int)rect.width;
list.Add(charInfo);
}
font.material = mat;
font.characterInfo = list.ToArray();
EditorUtility.SetDirty(font);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("更新成功");
}
Rect ConvertToPixels(Rect rect, int width, int height)
{
Rect r = rect;
r.xMin = Mathf.RoundToInt(rect.xMin * width);
r.xMax = Mathf.RoundToInt(rect.xMax * width);
r.yMin = Mathf.RoundToInt((1 - rect.yMax) * height);
r.yMax = Mathf.RoundToInt((1 - rect.yMin) * height);
return r;
}
Rect ConvertToTexCoords(Rect rect, int width, int height)
{
Rect r = rect;
if (width != 0 && height != 0)
{
r.xMin = rect.xMin / width;
r.xMax = rect.xMax / width;
r.yMin = 1 - rect.yMax / height;
r.yMax = 1 - rect.yMin / height;
}
return r;
}
List ac = new List();
void CombineTexture(string texSavePath)
{
ac.Clear();
int num = Selection.objects.Length;
if (num |