zoukankan      html  css  js  c++  java
  • UGUI使用BMFont制作美术字体<一>

    不多说,先来效果图:

    从头开始讲开发流程:

    在Unity3d开发过程中,经常需要将美术提供的美术字组合成一个字体库,方便unity中的调用,BMFont则为此提供了不错的功能支持,它的下载地址在这里。它的使用方法网上有很多教程,这里不做解释,如果要使用此工具,要注意的是,这里记得使用xml格式,导出的图片为一张。

    导出来的资源有:对应的图片,还有一个以fnt结尾的文件,如果打开此文件可以看到它就是一个xml文件:

    在BMFont软件中我们这样操作:Options->Save configuration as...,把这个文件保存下来,它是以bmfc结尾的,保存了在bmfont里面相关的配置属性,其中对应的文字图片还有对应的值在imported icon images中保存,用记事本打开,就可以可到这样的界面:

    以我的直觉,BMFont就是根据这样的一个配置文件生成对应的图片和xml文件。现在回到Unity,将BMFont生成的xml和图片分别拖动到1,2位置,点击Generate Font在对应的xml目录下便会生成字体文件和材质球,并且分别已经赋值,将字体拖动到ugui中的字体位置可见:

    这样一个工具算是完成了,它的代码在这里,自己也可以进行修改。但是作为懒癌的我,觉得这样极不方便,制作字体时候,每次都要打开bmfont,然后导入unity,再接着将文件拖动到相关位置,还要点击生成字体,简直不能忍受,那么下一篇我们制作一个更加方便的工具。

    using System.Collections.Generic;
    using System.IO;
    using System.Xml;
    using UnityEditor;
    using UnityEngine;
    
    public class BMFont : EditorWindow
    {
        private TextAsset _fontTextAsset;
        private Texture _fontTexture;
        private string _fontsDir;
    
        [MenuItem("CTools/BMFont", false, 12)]
        private static void BMFontTools()
        {
            BMFont bmFont = new BMFont();
            bmFont.Show();
        }
    
        private string _getAssetPath(string path)
        {
            string pathTemp = path.Replace("\", "/");
            pathTemp = pathTemp.Replace(Application.dataPath, "Assets");
            return pathTemp;
        }
    
        void OnGUI()
        {
            EditorGUILayout.BeginVertical();
            TextAsset taTemp = EditorGUILayout.ObjectField("选择Font文件:", _fontTextAsset, typeof(TextAsset), true) as TextAsset;
            if (taTemp != _fontTextAsset && taTemp != null)
            {
                string assetDir = Directory.GetParent(AssetDatabase.GetAssetPath(taTemp)).FullName;
                assetDir = _getAssetPath(assetDir);
                string imgPath = string.Format("{0}/{1}_0.png", assetDir, taTemp.name);
                _fontTexture = AssetDatabase.LoadAssetAtPath<Texture>(imgPath);
                _fontsDir = string.Format("{0}.fontsettings", Path.Combine(assetDir, taTemp.name));
                if (_fontTexture == null)
                {
                    _fontsDir = string.Empty;
                    Debug.LogError(string.Format("未发现{0}文件", imgPath));
                }
            }
            _fontTextAsset = taTemp;
    
            _fontTexture = EditorGUILayout.ObjectField("选择Font图片文件:", _fontTexture, typeof(Texture), true) as Texture;
    
            GUI.enabled = false;
            _fontsDir = EditorGUILayout.TextField("字体生成路径:", _fontsDir);
            GUI.enabled = true;
            if (GUILayout.Button("Generate Font"))
            {
                if (!string.IsNullOrEmpty(_fontsDir))
                {
                    Material mat = AssetDatabase.LoadAssetAtPath<Material>(_fontsDir.Replace(".fontsettings", ".mat"));
                    if (mat == null)
                    {
                        mat = new Material(Shader.Find("UI/Default Font"));
                        AssetDatabase.CreateAsset(mat, _fontsDir.Replace(".fontsettings", ".mat"));
                    }
                    if (_fontTexture != null)
                    {
                        mat = AssetDatabase.LoadAssetAtPath<Material>(_fontsDir.Replace(".fontsettings", ".mat"));
                        mat.SetTexture("_MainTex", _fontTexture);
                    }
                    else
                    {
                        Debug.LogError("贴图未做配置,请检查配置");
                        return;
                    }
    
                    Font font = AssetDatabase.LoadAssetAtPath<Font>(_fontsDir);
                    if (font == null)
                    {
                        font = new Font();
                        AssetDatabase.CreateAsset(font, _fontsDir);
                    }
    
                    _setFontInfo(AssetDatabase.LoadAssetAtPath<Font>(_fontsDir),
                        AssetDatabase.GetAssetPath(_fontTextAsset),
                        _fontTexture);
                    font = AssetDatabase.LoadAssetAtPath<Font>(_fontsDir);
                    font.material = mat;
                }
                else
                {
                    Debug.LogError("创建失败,请检查配置");
                }
            }
            EditorGUILayout.EndVertical();
        }
    
        private void _setFontInfo(Font font, string fontConfig, Texture texture)
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(fontConfig);
            List<CharacterInfo> chtInfoList = new List<CharacterInfo>();
            XmlNode node = xml.SelectSingleNode("font/chars");
            foreach (XmlNode nd in node.ChildNodes)
            {
                XmlElement xe = (XmlElement)nd;
                int x = int.Parse(xe.GetAttribute("x"));
                int y = int.Parse(xe.GetAttribute("y"));
                int width = int.Parse(xe.GetAttribute("width"));
                int height = int.Parse(xe.GetAttribute("height"));
                int advance = int.Parse(xe.GetAttribute("xadvance"));
                CharacterInfo info = new CharacterInfo();
                info.glyphHeight = texture.height;
                info.glyphWidth = texture.width;
                info.index = int.Parse(xe.GetAttribute("id"));
                //这里注意下UV坐标系和从BMFont里得到的信息的坐标系是不一样的哦,前者左下角为(0,0),
                //右上角为(1,1)。而后者则是左上角上角为(0,0),右下角为(图宽,图高)
                info.uvTopLeft = new Vector2((float)x / texture.width, 1 - (float)y / texture.height);
                info.uvTopRight = new Vector2((float)(x + width) / texture.width, 1 - (float)y / texture.height);
                info.uvBottomLeft = new Vector2((float)x / texture.width, 1 - (float)(y + height) / texture.height);
                info.uvBottomRight = new Vector2((float)(x + width) / texture.width, 1 - (float)(y + height) / texture.height);
    
                info.minX = 0;
                info.minY = -height;
                info.maxX = width;
                info.maxY = 0;
    
                info.advance = advance;
    
                chtInfoList.Add(info);
            }
            font.characterInfo = chtInfoList.ToArray();
            AssetDatabase.Refresh();
        }
    }

    参考:

  • 相关阅读:
    自编码变分贝叶斯(转载)
    加载Pytorch中的预训练模型及部分结构的导入
    pytorch读入图片并显示np.transpose(np_image, [1, 2, 0])
    高斯分布、多维高斯分布、各向同性的高斯分布及多元高斯分布之间的KL散度
    pytorch中的上采样(上采样,转置卷积,上池化,PixelShuffle)
    卷积算法动画演示
    PL/SQL编程基础
    PL/SQL Dev 调试
    PL/SQL Dev的安装与连接远程数据库
    Bean Form DTO VO Entity
  • 原文地址:https://www.cnblogs.com/Yellow0-0River/p/9020016.html
Copyright © 2011-2022 走看看