2025
04-22

Unity创建艺术字体

首先创建艺术字体文件。

Unity创建艺术字体 - 雨松MOMO程序研究院 - 1
接着将sprite拖入FontList, 并且输入它对应的unicode字符,可以是中文也可以是数字,主要就是把字符和Sprite进行绑定。
Unity创建艺术字体 - 雨松MOMO程序研究院 - 2

点击生成字体,会创建3个文件,字体文件、材质文件、图集文件。

创建Text对象,拖入刚刚生成的字体文件到Font上,输入绑定的字符即可排版艺术字

Unity创建艺术字体 - 雨松MOMO程序研究院 - 3
欢迎大家来试试呀。

using System;
using System.Collections.Generic;
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;

[CreateAssetMenu(menuName ="艺术字/文件")]
public class UIFontAsset : ScriptableObject
{
    [System.Serializable]
    public class Font
    {
        //字符
        public char c;
        //贴图
        public Texture2D texture;
    }

    //图集大小
    public int Size = 256;
    //图集间距
    public int Pandding = 1;
    public List<Font> FontList = new List<Font>();
}

#if UNITY_EDITOR
[CustomEditor(typeof(UIFontAsset))]
public class UIFontAssetEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        if(GUILayout.Button("生成字体"))
        {
            UIFontAsset fontAsset = target as UIFontAsset;
            if (fontAsset != null && fontAsset.FontList!=null)
            {
                List<Texture2D> atlasTextures = new List<Texture2D>();
                Dictionary<Texture2D, int> ascii = new Dictionary<Texture2D, int>();
                foreach (var data in  fontAsset.FontList)
                {
                    if (data != null && data.texture)
                    {
                        var tex = data.texture;
                        Texture2D @out = new Texture2D(tex.width, tex.height, TextureFormat.RGBA32, false);
                        var width = tex.width;
                        var height = tex.height;
                        RenderTexture tmp = RenderTexture.GetTemporary(width,height,0,RenderTextureFormat.Default,RenderTextureReadWrite.sRGB);
                        Graphics.Blit(tex, tmp);
                        RenderTexture previous = RenderTexture.active;
                        RenderTexture.active = tmp;
                        Texture2D @new = new Texture2D(width, height);
                        @new.ReadPixels(new Rect(0, 0, width, height), 0, 0);
                        @new.Apply();
                        @out.SetPixels(0, 0, width, height, @new.GetPixels());
                        RenderTexture.active = previous;
                        RenderTexture.ReleaseTemporary(tmp);
                        atlasTextures.Add(@out);
                        ascii[@out] = Convert.ToInt32(data.c);
                    }
                }
                
                Texture2D atlas = new Texture2D(fontAsset.Size, fontAsset.Size, TextureFormat.RGBA32, false);
                var rects = atlas.PackTextures(atlasTextures.ToArray(), fontAsset.Pandding, fontAsset.Size);
                var path = AssetDatabase.GetAssetPath(fontAsset);
                var newPath = ChangeFileName(path, ".png");
                File.WriteAllBytes(newPath, atlas.EncodeToPNG());
                
                AssetDatabase.ImportAsset(newPath);
                TextureImporter importer = AssetImporter.GetAtPath(newPath) as TextureImporter;
                if (importer != null)
                {
                    importer.textureType = TextureImporterType.Sprite;
                    importer.mipmapEnabled = false;
                    importer.SaveAndReimport();
                }
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
                CharacterInfo[] infos = new CharacterInfo[atlasTextures.Count];
                for (int i = 0; i < atlasTextures.Count; i++)
                {
                    var info= new CharacterInfo();
                    var tex = atlasTextures[i];
                    info.index = ascii[tex];
                    info.uv = rects[i];
                    var w = tex.width;
                    var h= tex.height;
                    info.advance = w;
                    info.vert = new Rect(0, 0, w, -h);
                    infos[i] = info;
                }
                      
                Shader shader = Shader.Find("Unlit/Transparent");
                Material material = new Material(shader);
                material.mainTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(newPath);
                AssetDatabase.CreateAsset(material, ChangeFileName(path, ".mat"));
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
                var fontPath = ChangeFileName(path, ".fontsettings");
                Font font = AssetDatabase.LoadAssetAtPath<Font>(fontPath);
                bool hasFont = font != null;
                if (!hasFont)
                    font = new Font();
                font.material = material;
                font.name = Path.GetFileNameWithoutExtension(fontPath);
                font.characterInfo = infos;
                if(!hasFont)
                    AssetDatabase.CreateAsset(font,fontPath);
                else
                {
                    EditorUtility.SetDirty(font);
                    AssetDatabase.SaveAssetIfDirty(font);
                }
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
        }
    }
    string ChangeFileName(string path, string newName)
    {
        var directory = Path.GetDirectoryName(path);
        var newFileName =Path.GetFileNameWithoutExtension(path)+newName;
        return Path.Combine(directory, newFileName);
    }
}
#endif

 

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

Unity创建艺术字体》有 2 条评论

  1. xxx说:

    正好需要这个,感谢momo

留下一个回复

你的email不会被公开。 必填项已用 * 标注。