Unity3D-將美術提供的圖片當做字體使用(普通圖片自動生成Custom font)

參考:http://blog.csdn.net/pz789as/article/details/54313122

我在上一篇文章中寫了一個最新版本的導出fnt字體的方式,主要就是uv和vert的變化。
這兩天發現,有時候我們需要的藝術字體,並不是ttf這種字體格式的文件,而有可能是美術人員自己動手畫的藝術字,這個時候就沒法用上面那個方法去做圖片字體了。難道還能用手去填寫麼,那也太麻煩了。
本來想着自己寫個工具去切分然後導出,後面想到爲什麼不利用unity自帶的sprite editor呢?
於是在網上搜索,發現是可以寫一個編輯器腳本去讀取sprite的,而且是那種切分的sprite。
具體做法如下,版本是Unity5.5:
1、把字體圖片導入到unity中來,需要將文件放到Resources文件夾下面。看到這裏我想大家都明白怎麼弄了,對的,就是使用Resources.Load()的方法去加載;
2、設置圖片的格式爲sprite,sprite mode爲multiple,alpha source根據圖片去設置,帶了alpha的就選擇 input texture alpha,沒有的就選擇from gray scale,主要是設置透明;
這裏寫圖片描述

3、使用unity自帶的sprite edtior,將我們的藝術字體圖片一個一個的切分好,然後命名自己規範一下!我現在命名是使用的名字的最後一個字符去定義的,類似我下面的截圖:
這裏寫圖片描述
這樣做的好處是我們在代碼裏面得到這個字符的ascii碼,直接對應了字體裏面的index,而且看起來也直觀了當。當然如果是漢字的話,那麼就得自己去做一個映射了,使用一些不常用的字符去替換即可。
4、然後我們在看看這個還可以給我們提供什麼數據呢?那就是pivot了,一般來說我們做到這個一步就可以了,但是有一個額外的pivot爲什麼不利用起來呢!我現在是把這個當做一個偏移去用的,因爲有些符號:比如“,”、“.”這種,是需要居底顯示的。因此我就用這個來代替,但是具體要怎麼計算,就看大家各自的用處了。
5、準備資源完畢後,接下來就是寫代碼了,我就不多說了,直接貼上來吧:

//本方法是通過裁切的sprite導出字體文件,裁切使用的是unity自帶的sprite editor,方便操作。  
    //另外,裁切之後,每個sprite的名字的最後一個字符對應了ascii碼的編碼,比如:  
    //0: 我們只要將sprite的名字命名成xxx0,就可以了!  
    //由於使用到的了sprite加載,所以字體圖片請放在Resources目錄下面,等製作完畢,再把他們放到fonts文件夾或者其他文件夾中即可。  
    [MenuItem("Assets/CreateMyFontSprite")]  
    static void CreateMyFontSprite(){  
        if (Selection.objects == null) return;  
        if (Selection.objects.Length == 0) {  
            Debug.LogWarning("沒有選中Sprite文件,需要將Sprite Mode設置成Multiple,切分好,並且以以名字的最後一個字符當做ascii碼");  
            return;  
        }  
        string resoursePath = "Resources";  
        Object o = Selection.objects[0];  
        if (o.GetType() != typeof(Texture2D)){  
            Debug.LogWarning("選中的並不是圖片文件");  
            return;  
        }  
        string selectionPath = AssetDatabase.GetAssetPath(o);  
        if (selectionPath.Contains(resoursePath)){  
            string selectionExt = Path.GetExtension(selectionPath);  
            if (selectionExt.Length == 0){  
                return;  
            }  
            string loadPath = selectionPath.Remove(selectionPath.Length - selectionExt.Length);  
            string fontPathName = loadPath + ".fontsettings";  
            string matPathName = loadPath + ".mat";  
            float lineSpace = 0.1f;//字體行間距,下面會根據最高的字體得到行間距,如果是固定高度,可以在這裏自行調整  
            loadPath = Path.GetFileNameWithoutExtension(selectionPath);  
            Sprite[] sprites = Resources.LoadAll<Sprite>(loadPath);  
            if (sprites.Length>0){  
                //以textrue方式獲得該資源,可以設置到創建的材質中去  
                Texture2D tex = o as Texture2D;  
                //創建字體材質,並且將圖片設置好  
                Material mat = new Material(Shader.Find("GUI/Text Shader"));  
                AssetDatabase.CreateAsset(mat, matPathName);  
                mat.SetTexture("_MainTex", tex);  
                //創建字體文件,設置字體文件的材質  
                Font m_myFont = new Font();  
                m_myFont.material = mat;  
                AssetDatabase.CreateAsset(m_myFont, fontPathName);  
                //創建字體中的字符集數組  
                CharacterInfo[] characterInfo = new CharacterInfo[sprites.Length];   
                //得到最高的高度,設置行高和進行偏移計算  
                for(int i=0;i<sprites.Length;i++){  
                    if (sprites[i].rect.height > lineSpace){  
                        lineSpace = sprites[i].rect.height;  
                    }  
                }  
                for(int i=0;i<sprites.Length;i++){  
                    Sprite spr = sprites[i];  
                    CharacterInfo info = new CharacterInfo();  
                    //設置ascii碼,使用切分sprite的最後一個字母  
                    info.index = (int)spr.name[spr.name.Length-1];  
                    Rect rect = spr.rect;  
                    //根據pivot設置字符的偏移,具體需要做成什麼樣的,可以根據自己需要修改公式  
                    float pivot = spr.pivot.y/rect.height - 0.5f;  
                    if (pivot > 0){  
                        pivot = -lineSpace/2 - spr.pivot.y;  
                    }else if (pivot < 0){  
                        pivot = -lineSpace/2 + rect.height - spr.pivot.y;  
                    }else{  
                        pivot = -lineSpace/2;  
                    }  
                    Debug.Log(pivot);  
                    int offsetY = (int)(pivot + (lineSpace - rect.height)/2);  
                    //設置字符映射到材質上的座標  
                    info.uvBottomLeft = new Vector2((float)rect.x/tex.width, (float)(rect.y)/tex.height);  
                    info.uvBottomRight = new Vector2((float)(rect.x+rect.width)/tex.width, (float)(rect.y)/tex.height);  
                    info.uvTopLeft = new Vector2((float)rect.x/tex.width, (float)(rect.y+rect.height)/tex.height);  
                    info.uvTopRight = new Vector2((float)(rect.x+rect.width)/tex.width, (float)(rect.y+rect.height)/tex.height);  
                    //設置字符頂點的偏移位置和寬高  
                    info.minX = 0;  
                    info.minY = -(int)rect.height-offsetY;  
                    info.maxX = (int)rect.width;  
                    info.maxY = -offsetY;  
                    //設置字符的寬度  
                    info.advance = (int)rect.width;  
                    characterInfo[i] = info;  
                }  
                // lineSpace += 2;  
                m_myFont.characterInfo = characterInfo;  
                EditorUtility.SetDirty(m_myFont);//設置變更過的資源  
                AssetDatabase.SaveAssets();//保存變更的資源  
                AssetDatabase.Refresh();//刷新資源,貌似在Mac上不起作用  

                //由於上面fresh之後在編輯器中依然沒有刷新,所以暫時想到這個方法,  
                //先把生成的字體導出成一個包,然後再重新導入進來,這樣就可以直接刷新了  
                //這是在Mac上遇到的,不知道Windows下面會不會出現,如果不出現可以把下面這一步註釋掉  
                AssetDatabase.ExportPackage(fontPathName, "temp.unitypackage");  
                AssetDatabase.DeleteAsset(fontPathName);  
                AssetDatabase.ImportPackage("temp.unitypackage", true);  
                AssetDatabase.Refresh();  

                //最佳高度:上下各留一個像素的間距,如果不需要可以註釋掉,根據需求更改  
                //打印是爲了使使用者方便填寫行高,因爲font不支持設置行高。  
                Debug.Log("創建字體成功, 最大高度:" + lineSpace + ", 最佳高度:" + (lineSpace+2));  
            }else{  
                Debug.LogWarning("沒有選中Sprite文件,需要將Sprite放到Resources文件夾下面,可以參考函數上方的說明操作");  
            }  
        }  
    }  

這個方法的好處就是不需要使用BMFont軟件去導出字體數據了,而且可以做各種自己需要的字體或者圖片效果。我這裏也沿用了前一篇文章的做飯,只需要選擇這個圖片文件,然後點菜單欄中的按鈕就可以生成想要的字體咯!

注意的地方:
1、圖片的設置格式;
2、圖片放置的位置;
3、切分圖片的名字;
4、最最重要的是,當你把字體做完之後,需要將圖片格式重新設置成Default,不然上了真機會出現你想不到的效果~
微笑

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章