Unity3d之-使用BMFont製作美術字體
一、需求
遊戲開發中經常遇到需要以美術字(而非字型檔)做數字顯示的情況,通常美術會提供一組包含單個數字(也會有其它字元)的圖片,可能是一張整圖,也可能是每個數字分開的散圖。
在此我以一張整圖這種情況為例,來說明美術字體的具體制作流程。整圖如下:
二、準備
整個製作過程需要用到三樣工具:
- 字型資料製作工具
- 圖片切割工具
- 字型生成工具
1、字型資料製作工具
字型資料製作工具名為BMFont,是一個Windows上的可執行軟體,下載網址為: http://www.angelcode.com/products/bmfont/
這裡選擇下載64位執行版(單體檔案,無需安裝)
可也以點這裡下載:BMFont64.exe
2、圖片切割工具
圖片切割工具是Unity中執行的一個工具類,類名為ImageSlicer,放在Editor目錄下即可,程式碼如下:
1 /** 2 * UnityVersion: 2018.3.10f1 3 * FileName:ImageSlicer.cs 4 * Author:TYQ 5 * CreateTime:2019/04/19 00:04:26 6 * Description: 7 */ 8 /* 9 * Author: 10 * Date:2019/01/30 10:24:22 11 * Desc:圖集切割器 (針對Multiple格式的圖片) 12 * 操作方式:選中圖片,選擇編輯器的 Assets/ImageSlicer/Process to Sprites選單 13 */ 14 15 using UnityEngine; 16 using System.Collections; 17 using UnityEditor; 18 using System.IO; 19 using System.Collections.Generic; 20 21 public static class ImageSlicer 22 { 23[MenuItem("Assets/ImageSlicer/Process to Sprites")] 24static void ProcessToSprite() 25{ 26Texture2D image = Selection.activeObject as Texture2D;//獲取旋轉的物件 27string rootPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(image));//獲取路徑名稱 28string path = rootPath + "/" + image.name + ".PNG";//圖片路徑名稱 29 30 31TextureImporter texImp = AssetImporter.GetAtPath(path) as TextureImporter;//獲取圖片入口 32 33 34AssetDatabase.CreateFolder(rootPath, image.name);//建立資料夾 35 36 37foreach (SpriteMetaData metaData in texImp.spritesheet)//遍歷小圖集 38{ 39Texture2D myimage = new Texture2D((int)metaData.rect.width, (int)metaData.rect.height); 40 41//abc_0:(x:2.00, y:400.00, width:103.00, height:112.00) 42for (int y = (int)metaData.rect.y; y < metaData.rect.y + metaData.rect.height; y++)//Y軸畫素 43{ 44for (int x = (int)metaData.rect.x; x < metaData.rect.x + metaData.rect.width; x++) 45myimage.SetPixel(x - (int)metaData.rect.x, y - (int)metaData.rect.y, image.GetPixel(x, y)); 46} 47 48 49//轉換紋理到EncodeToPNG相容格式 50if (myimage.format != TextureFormat.ARGB32 && myimage.format != TextureFormat.RGB24) 51{ 52Texture2D newTexture = new Texture2D(myimage.width, myimage.height); 53newTexture.SetPixels(myimage.GetPixels(0), 0); 54myimage = newTexture; 55} 56var pngData = myimage.EncodeToPNG(); 57 58 59//AssetDatabase.CreateAsset(myimage, rootPath + "/" + image.name + "/" + metaData.name + ".PNG"); 60File.WriteAllBytes(rootPath + "/" + image.name + "/" + metaData.name + ".PNG", pngData); 61// 重新整理資源視窗介面 62AssetDatabase.Refresh(); 63} 64} 65 } ImageSlicer.cs
編譯完成後會在Assets選單下生成一個 ImageSlicer/Process to Sprites 的選單項,選中圖片然後右鍵也可以看到。
3、字型生成工具
字型生成工具也是Unity3d中一個第三方外掛,名字也是BMFont(不知道和第一個軟體有什麼關聯)。原本是NGUI中的一個字體制作工具,現被大佬剝離出來,在UGUI中也可以使用。
下載地址:BMFont字型生成工具
解壓到Assets目錄下即可,編譯完成後,會在Unity編輯器上生成一個Tools/BMFont Maker選單。
三、開始製作
1、切割圖片
在字型資料製作軟體BMFont64中,需要使用單個數字的圖片,而我這個是一張包含所有數字和字母符號的整圖,就需要切成單張散圖。
a) 把圖片匯入Unity,Sprite Mode選擇Multiple模式,勾選Read/Write Enable選項。見下圖:
然後點選Sprite Editor進行多圖區域編輯,如下圖。可以先按給定的三種方式進行劃分,自己再做細微調整。注意每個字元邊距不要太大,不然做成字型後顯示起來就會很離散。
分割完成後,點選Apply儲存操作。
b) 選中圖片右鍵,執行 ImageSlicer/Process to Sprites 選單,會生成一個與圖片同名的目錄,裡邊放著切割好的散圖。見下圖,
2、製作字型資料
a) 開啟BMFont64軟體,點選Edit下的Open Image Manager選單。
在開啟的Image Manager視窗有一個 Image 選單,可以進行圖片匯入、編輯和刪除操作。
操作方式:這裡以逗號字元為例,滑鼠放在主視窗逗號方格的位置,右下會顯示其編號,記住這個編號。
然後在Image Manager視窗中選擇匯入圖片,選中切割成散圖的逗號圖片,在Icon Image彈窗的Id中填入逗號方格的編號:44,點選Ok。
依樣匯入其它的圖片,並填入Id值,最後的完成圖如下:每個字元方格的編號,對應一個相應的圖片。
b) 點選Options/Export options選單,
開啟匯出選項視窗,這裡邊主要設定一個合成圖片的寬和高,以及匯出格式。
這個軟體的最後一步操作是匯出字型資料,包括一個字型資料檔案(.fnt格式)和一張紋理圖。這個紋理圖會把所有的單圖又合成一張。
這裡的Width是指這張合成紋理的總寬度(最好比所有圖片加起來的數值要大一點,因為每個數字圖片合成時會有一個px的間隔),
Height是單個圖片的高度(最好比圖片高1畫素以上)。
不能一次設定準確也沒關係,可以點選Options/Visualize選單預覽合成效果,再微調高寬值,最終讓所有圖片都能剛剛顯示為好。
合成圖預覽如下:
c) 點選Options/Save bitmap font as..選單,選擇位置後進行儲存操作,最終會得到兩個檔案(ArtNum.fnt和ArtNum_0.png),如下圖:
字型名字可以自由定義,匯出的時候,每個方格要處在選中狀態(淺灰色)。
關於BMFont64軟體的操作,也可以參考文章: Unity教程之-UGUI美術字體的製作與使用
3、生成字型
a)將上述兩個檔案匯入到Unity中,在資源面板中滑鼠右鍵,選擇 Create/Material 和 Create/Custom Font 選單,
建立一個空的材質ArtNum_mat和一個空的自定義字型ArtNum(字尾為.fontsettings,在Unity中不顯示),如下圖:
b) 點選Tools/BMFont Maker選單,在開啟的視窗中,選擇相應的檔案進行賦值,如下圖,
最後點選Create BMFont按鈕,這樣一個美術字體就生成了。
點選字型檔案,能在Inspector面板的Character Rects中看到字型的對映資訊。
c) 建立一個Text,輸入一些數字字母和符號,字型選擇為ArtNum,顏色選為白色,就能看到實際的效果。
美術字體制作完成。
後記
使用這種字型的一些小問題
1、字型不會換行,超出寬度的字型將會重疊顯示,需要預留出寬度。
2、字型不受Font Size的影響,無法動態調整大小,如有需要,可通過設定Scale來解決。