1. 程式人生 > 其它 >Unity 美術字圖片 生成 字型Font

Unity 美術字圖片 生成 字型Font

技術標籤:遊戲開發unity3d

簡介

有時候,美術會提供圖片(大部分是數字效果),Unity需要在Text元件使用這些美術效果,這時候可以把這些圖片製作成一個Font(字型檔案),供Text使用。


一、使用BmFont工具


注:工具直接搜尋下載即可,同時會有使用步驟教程!
使用BmFont工具最終產出兩個資源:
.fnt :該檔案是字元的配置
.png :相當於圖片資源集合


二、使用編輯工具(Unity)生成最終資源

1、將生成的.fnt 和 .png 檔案匯入Unity
2、將.png 在Inspector面板中將Texture Type設定成Sprite(2D and UI)

3、開啟編輯器工具(編輯器程式碼見文章下方)
在這裡插入圖片描述
Font Texture:選擇上邊匯入設定成的Sprite
BMFont fnt:選擇.fnt檔案
最後點選生成。

4、生成結果:
在這裡插入圖片描述

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;


public class BMFontEditor : EditorWindow
{
    public TextAsset fontPosTbl;
    public Texture fontTexture;
    public Vector2 scrollPos;
struct ChrRect { public int id; public int x; public int y; public int w; public int h; public int xofs; public int yofs; public int index; public float uvX; public float uvY; public float uvW; public
float uvH; public float vertX; public float vertY; public float vertW; public float vertH; public float width; } // add menu [MenuItem("工具選單/美術/生成字型")] static void Init() { EditorWindow.GetWindow(typeof(BMFontEditor)); } void OnGUI() { EditorGUILayout.BeginVertical(); fontTexture = (Texture)EditorGUILayout.ObjectField("Font Texture(Sprite格式)", fontTexture, typeof(Texture), false); EditorGUILayout.Space(); EditorGUILayout.LabelField("Use BMFont fnt File", EditorStyles.boldLabel); EditorGUILayout.LabelField("(must Font Descriptor select Text)", EditorStyles.boldLabel); fontPosTbl = (TextAsset)EditorGUILayout.ObjectField("BMFont fnt (.fnt)", fontPosTbl, typeof(TextAsset), false); if (GUILayout.Button("Create")) { if (fontTexture == null) this.ShowNotification(new GUIContent("No Font Texture selected")); else if (fontPosTbl == null) this.ShowNotification(new GUIContent("No Font Position Table file selected")); else { CalcChrRect(fontPosTbl, fontTexture); } } EditorGUILayout.LabelField("輸出路徑在.fnt檔案的同級目錄", EditorStyles.largeLabel); EditorGUILayout.EndVertical(); } void OnInspectorUpdate() { this.Repaint(); } void CalcChrRect(TextAsset posTbl, Texture tex) { string fileName = AssetDatabase.GetAssetPath(fontPosTbl); string texName = AssetDatabase.GetAssetPath(tex); string fontName = System.IO.Path.GetFileNameWithoutExtension(fileName); string fontPath = fileName.Replace(".fnt", ".fontsettings"); string matPath = fileName.Replace(".fnt", ".mat"); float imgw = (float)tex.width; float imgh = (float)tex.height; string txt = posTbl.text; List<ChrRect> tblList = new List<ChrRect>(); foreach (string line in txt.Split('\n')) { if (line.IndexOf("char id=") == 0) { ChrRect d = GetChrRect(line, imgw, imgh); tblList.Add(d); } } if (tblList.Count == 0) { new GUIContent("Failed"); return; } ChrRect[] tbls = tblList.ToArray(); Font font = new Font(); font.name = fontName; SetCharacterInfo(tbls, font); Material mat = new Material(Shader.Find("Unlit/Transparent")); mat.mainTexture = tex; mat.name = fontName; font.material = mat; Debug.Log(System.IO.Path.GetFileNameWithoutExtension(fileName)); Debug.Log(fileName); AssetDatabase.CreateAsset(mat, matPath); AssetDatabase.CreateAsset(font, fontPath); AssetDatabase.SaveAssets(); this.ShowNotification(new GUIContent("Complete")); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); } void SetCharacterInfo(ChrRect[] tbls, Font fontObj) { CharacterInfo[] nci = new CharacterInfo[tbls.Length]; for (int i = 0; i < tbls.Length; i++) { nci[i].index = tbls[i].index; nci[i].advance = (int)tbls[i].width; nci[i].uv.x = tbls[i].uvX; nci[i].uv.y = tbls[i].uvY; nci[i].uv.width = tbls[i].uvW; nci[i].uv.height = tbls[i].uvH; nci[i].vert.x = tbls[i].vertX; nci[i].vert.y = tbls[i].vertY; nci[i].vert.width = tbls[i].vertW; nci[i].vert.height = tbls[i].vertH; } fontObj.characterInfo = nci; } ChrRect GetChrRect(string line, float imgw, float imgh) { ChrRect d = new ChrRect(); foreach (string s in line.Split(' ')) { if (s.IndexOf("id=") >= 0) d.id = GetParamInt(s, "id="); else if (s.IndexOf("x=") >= 0) d.x = GetParamInt(s, "x="); else if (s.IndexOf("y=") >= 0) d.y = GetParamInt(s, "y="); else if (s.IndexOf("width=") >= 0) d.w = GetParamInt(s, "width="); else if (s.IndexOf("height=") >= 0) d.h = GetParamInt(s, "height="); else if (s.IndexOf("xoffset=") >= 0) d.xofs = GetParamInt(s, "xoffset="); else if (s.IndexOf("yoffset=") >= 0) d.yofs = GetParamInt(s, "yoffset="); else if (s.IndexOf("xadvance=") >= 0) d.width = GetParamInt(s, "xadvance="); } d.index = d.id; d.uvX = (float)d.x / imgw; d.uvY = (float)(imgh - (d.y)) / imgh; d.uvW = (float)d.w / imgw; //d.uvH = (float)-d.h / imgh; d.uvH = (float)-d.h / imgh; d.vertX = (float)d.xofs; d.vertY = (float)d.yofs; d.vertW = d.w; d.vertH = d.h; return d; } int GetParamInt(string s, string wd) { if (s.IndexOf(wd) >= 0) { int v; if (int.TryParse(s.Substring(wd.Length), out v)) return v; } return int.MaxValue; } }