點陣圖字型匯入

请明月發表於2024-10-17
/// <summary>
/// 點陣圖字型生成工具
/// </summary>
public class BMFontTool
{
    /// <summary>
    /// 字型生成
    /// </summary>
    [MenuItem("Assets/BMFont/CreateFont")]
    static void CreateFont()
    {
        string directorPath;
        //選中的asset路徑
        string assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
        if (string.IsNullOrEmpty(assetPath)) return;
        //設定資料夾路徑
        if (AssetDatabase.IsValidFolder(assetPath))
        {
            directorPath = assetPath;
        }
        else
        {
            int endIndex = assetPath.LastIndexOf('/');
            directorPath = assetPath.Substring(0, endIndex + 1);
        }
        //找到.fnt檔案和.fontsetting檔案
        string fntPath;
        var fntList = GetAllAssetPathsInFolder(directorPath, ".fnt");
        if (fntList.Count > 0)
        {
            fntPath = fntList[0];
            if (string.IsNullOrEmpty(fntPath))
            {
                Debug.LogError("沒有找到.fnt檔案,請檢查生成");
                return;
            }
        }
        else
        {
            Debug.LogError("沒有找到.fnt檔案,請檢查生成");
            return;
        }

        string fontsettingPath;
        var settingList = GetAllAssetPathsInFolder(directorPath, ".fontsetting");
        if (settingList.Count > 0)
        {
            fontsettingPath = settingList[0];
            if (string.IsNullOrEmpty(fontsettingPath))
            {
                Debug.LogError("沒有找到.fontsetting檔案,請檢查是否建立");
                return;
            }
        }
        else
        {
            Debug.LogError("沒有找到.fontsetting檔案,請檢查是否建立");
            return;
        }

        //根據選中物體判斷是資源還是資料夾,然後獲取資料夾下的.fnt和.fontsetting
        TextAsset fntFile = AssetDatabase.LoadAssetAtPath<TextAsset>(fntPath);
        Font fontFile = AssetDatabase.LoadAssetAtPath<Font>(fontsettingPath);
        
        //讀取進入字型檔案
        ReadFntToSetting(fontFile, fntFile);
        
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }

    /// <summary>
    /// 讀取fnt檔案進入fontsetting檔案
    /// </summary>
    /// <param name="font">fontsetting檔案</param>
    /// <param name="textAsset">fnt檔案</param>
    static void ReadFntToSetting(Font font,TextAsset textAsset)
    {
        if (font == null || textAsset == null)
        {
            //Debug.LogError("請設定font和textAsset.");
            return;
        }
        ArrayList characterInfoList = new ArrayList();

        string[] allLine = textAsset.text.Split('\n');
        string[] cInfo = allLine[1].Split(' ');
        //獲取總高度、總寬度
        int totalWidth = Convert.ToInt32(cInfo[3].Split('=')[1]);
        int totalHeight = Convert.ToInt32(cInfo[4].Split('=')[1]);
        //讀取正確資料容量
        string[] lInfo = allLine[3].Split(' ');
        int count = Convert.ToInt32(lInfo[1].Split('=')[1]);

        //資料內容讀取
        for (int i = 4; i < 4 + count; i++)
        {
            string line = allLine[i];
            // Define the regular expression pattern
            string pattern = @"\d+";

            // Create a Regex object
            Regex regex = new Regex(pattern);

            // Find all matches
            MatchCollection matches = regex.Matches(line);
            
            int index = Convert.ToInt32(matches[0].Value);
            int x = Convert.ToInt32(matches[1].Value);
            int y = Convert.ToInt32(matches[2].Value);
            int width = Convert.ToInt32(matches[3].Value);
            int height = Convert.ToInt32(matches[4].Value);
            int xOffset = Convert.ToInt32(matches[5].Value);
            int yOffset = Convert.ToInt32(matches[6].Value);
            int xAdvance = Convert.ToInt32(matches[7].Value);

            CharacterInfo charInfo = new CharacterInfo();
            Rect uv = new Rect();
            uv.x = (float)x / totalWidth;
            uv.y = (float)(totalHeight - y - height) / totalHeight;
            uv.width = (float)width / totalWidth;
            uv.height = (float)height / totalHeight;
            charInfo.index = index;
            charInfo.uvBottomLeft = new Vector2(uv.xMin, uv.yMin);
            charInfo.uvBottomRight = new Vector2(uv.xMax, uv.yMin);
            charInfo.uvTopLeft = new Vector2(uv.xMin, uv.yMax);
            charInfo.uvTopRight = new Vector2(uv.xMax, uv.yMax);
            charInfo.minX = xOffset;
            charInfo.maxX = xOffset + width;
            charInfo.minY = -yOffset - height;
            charInfo.maxY = -yOffset;
            charInfo.advance = xAdvance;
            charInfo.glyphWidth = width;
            charInfo.glyphHeight = height;
            characterInfoList.Add(charInfo);
        }
        font.characterInfo = characterInfoList.ToArray(typeof(CharacterInfo)) as CharacterInfo[];
        Debug.Log("生成成功.");
    }

    /// <summary>
    /// 獲取匹配的路徑
    /// </summary>
    /// <param name="folderPath">資料夾路徑</param>
    /// <param name="filter">匹配字串</param>
    /// <returns>路徑列表</returns>
    public static List<string> GetAllAssetPathsInFolder(string folderPath,string filter)
    {
        List<string> filepaths = new List<string>();

        // 獲取指定資料夾下的所有直接子資源路徑
        string[] subfoldersAndFiles = AssetDatabase.FindAssets("", new string[] { folderPath });

        foreach (string guid in subfoldersAndFiles)
        {
            string assetPath = AssetDatabase.GUIDToAssetPath(guid);

            // 確保是檔案而不是資料夾
            if (!AssetDatabase.IsValidFolder(assetPath))
            {
                // 提取檔名並新增到列表中
                string filename = Path.GetFileName(assetPath);
                if (filename.Contains(filter))
                {
                    filepaths.Add(assetPath);
                }
            }
        }

        return filepaths;
    }
}

相關文章