유 니 티 가 사용자 정의 글꼴 을 만 드 는 두 가지 방법

13072 단어 Unity글씨체
유 니 티 는 사용자 정의 그림 글꼴(CustomFont)을 지원 합 니 다.인터넷 에는 많은 튜 토리 얼 이 있 고 디 테 일이 다 릅 니 다.요약 하면 기본적으로 두 가지 방식 입 니 다.첫째,BMFont 을 사용 하여 그림 집합 과.fnt 파일 을 내 보 내 고,그림 집합 을 사용 하여 Unity 에 글꼴 을 설정 합 니 다.둘 째 는 BMFont 을 사용 하지 않 고 Unity 가 자체 적 으로 가지 고 있 는 Sprite 와 유사 한 그림 집합 기능 을 사용 하 는 것 이다.두 가지 방식 의 원 리 는 같 지만 수단 만 차이 가 있다.기본 원 리 는 모두 먼저 스티커 가 있다.예 를 들 어:

알 아야 할 정 보 는 스티커 에 있 는 모든 문자 에 대응 하 는 ASCII 코드(예 를 들 어 0 의 ASCII 코드 는 48)와 이 문자 가 그림 집합 에 대응 하 는 위치(0 은 x:0;y:0;w:55;h:76)。그리고 유 니 티 에 소재 와 CustomFont 을 만 들 고 정보 에 따라 설정 합 니 다.

마지막 으로 글꼴 을 얻 습 니 다.

두 가지 방식 의 차 이 는 첫 번 째 단계 에서 앨범 의 정 보 를 어떻게 얻 느 냐 에 있다.구체 적:
첫 번 째 BMFont 을 사용 하 는 방식 은'fnt 파일'을 얻 기 위해 서 이 며,실제로는 xml 형식 파일 입 니 다.구체 적 인 정 보 는 다음 과 같다.

BMFont 의 사용 방법 은 더 이상 상술 하지 않 습 니 다.그림 집합 fnt 파일 을 얻 은 후 인터넷 에서 일반적인 방법 은 유 니 티 에 있 는 인 자 를 수 동 으로 계산 하 는 것 입 니 다.좀 번 거 롭 습 니 다.여기 서 Editor 스 크 립 트 를 써 서 이 과정 을 자동 으로 완성 합 니 다.직접 코드 올 리 기:

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEditor;
using UnityEngine;
 
public class CreateFontFromFnt : EditorWindow
{
 [MenuItem("Tools/    (Fnt)")]
 static void DoIt()
 {
  GetWindow<CreateFontFromFnt>("    ");
 }
 private string fontName;
 private string fontPath;
 private Texture2D tex;
 private string fntFilePath;
 
 private void OnGUI()
 {
  GUILayout.BeginVertical();
 
  GUILayout.BeginHorizontal();
  GUILayout.Label("    :");
  fontName = EditorGUILayout.TextField(fontName);
  GUILayout.EndHorizontal();
 
  GUILayout.BeginHorizontal();
  GUILayout.Label("    :");
  tex = (Texture2D)EditorGUILayout.ObjectField(tex, typeof(Texture2D), true);
  GUILayout.EndHorizontal();
 
  GUILayout.BeginHorizontal();
  if (GUILayout.Button(string.IsNullOrEmpty(fontPath) ? "    " : fontPath))
  {
   fontPath = EditorUtility.OpenFolderPanel("    ", Application.dataPath, "");
   if (string.IsNullOrEmpty(fontPath))
   {
    Debug.Log("      ");
   }
   else
   {
    fontPath = fontPath.Replace(Application.dataPath, "") + "/";
   }
  }
  GUILayout.EndHorizontal();
 
  GUILayout.BeginHorizontal();
  if (GUILayout.Button(string.IsNullOrEmpty(fntFilePath) ? "  fnt  " : fntFilePath))
  {
   fntFilePath = EditorUtility.OpenFilePanelWithFilters("  fnt  ", Environment.GetFolderPath(Environment.SpecialFolder.Desktop), new string[] { "", "fnt" });
   if (string.IsNullOrEmpty(fntFilePath))
   {
    Debug.Log("      ");
   }
  }
  GUILayout.EndHorizontal();
 
  GUILayout.BeginHorizontal();
  if (GUILayout.Button("  "))
  {
   Create();
  }
  GUILayout.EndHorizontal();
 
  GUILayout.EndVertical();
 }
 
 private void Create()
 {
  if (string.IsNullOrEmpty(fntFilePath))
  {
   Debug.LogError("fnt  ");
   return;
  }
  if (tex == null)
  {
   Debug.LogError("      ");
   return;
  }
 
  string fontSettingPath = fontPath + fontName + ".fontsettings";
  string matPath = fontPath + fontName + ".mat";
  if (File.Exists(Application.dataPath + fontSettingPath))
  {
   Debug.LogErrorFormat("         :{0}", fontSettingPath);
   return;
  }
  if (File.Exists(Application.dataPath + matPath))
  {
   Debug.LogErrorFormat("         :{0}", matPath);
   return;
  }
  var list = new List<CharacterInfo>();
  XmlDocument xmlDoc = new XmlDocument();
  var content = File.ReadAllText(fntFilePath, System.Text.Encoding.UTF8);
  xmlDoc.LoadXml(content);
  var nodelist = xmlDoc.SelectNodes("font/chars/char");
  foreach (XmlElement item in nodelist)
  {
   CharacterInfo info = new CharacterInfo();
   var id = int.Parse(item.GetAttribute("id"));
   var x = float.Parse(item.GetAttribute("x"));
   var y = float.Parse(item.GetAttribute("y"));
   var width = float.Parse(item.GetAttribute("width"));
   var height = float.Parse(item.GetAttribute("height"));
 
   info.index = id;
   //    ,    
   info.uvBottomLeft = new Vector2(x / tex.width, 1 - (y + height) / tex.height);
   info.uvBottomRight = new Vector2((x + width) / tex.width, 1 - (y + height) / tex.height);
   info.uvTopLeft = new Vector2(x / tex.width, 1 - y / tex.height);
   info.uvTopRight = new Vector2((x + width) / tex.width, 1 - y / tex.height);
 
   info.minX = 0;
   info.maxX = (int)width;
   info.minY = -(int)height / 2;
   info.maxY = (int)height / 2;
   info.advance = (int)width;
 
   list.Add(info);
  }
 
  Material mat = new Material(Shader.Find("GUI/Text Shader"));
  mat.SetTexture("_MainTex", tex);
  Font m_myFont = new Font();
  m_myFont.material = mat;
  AssetDatabase.CreateAsset(mat, "Assets" + matPath);
  AssetDatabase.CreateAsset(m_myFont, "Assets" + fontSettingPath);
  m_myFont.characterInfo = list.ToArray();
  EditorUtility.SetDirty(m_myFont);
  AssetDatabase.SaveAssets();
  AssetDatabase.Refresh();
  Debug.Log("    !");
 }
}
사용 하기 쉽다:

코드 도 깊이 연구 할 만 한 것 이 없 는데 수 동 계산 을 대체 하 는 것 이 목적 이 고 무늬 가 비 칠 때 작은 구멍 이 있 을 뿐이다.
두 번 째 방식 은 Unity 의 Sprite 를 사용 합 니 다.Unity 는 하나의 Sprite 를 여러 개 로 자 르 는 것 을 지원 합 니 다.BMFont 에서 내 보 낸 fnt 파일 을 이런 식 으로 대체 할 수 있 습 니 다.수 동 으로 해 야 할 작업 은 그림 집의 Texture Type 을 Sprite 로 설정 한 다음 Sprite Mode 를 Multiple 로 설정 하고 Sprite Editor 를 열 어 그림 을 자 르 는 것 입 니 다.Slice 는 기본적으로 이 일 을 완성 할 수 있 습 니 다.만약 에 수 동 으로 미세 조정 이 필요 하 다 면.

한 장의 그림 이 문자 의 위치 에 따라 10 개의 Sprite 로 나 뉘 었 다.그리고 모든 Sprite 를 선택 하여 Name 을 문자 에 대응 하 는 ASCII 코드 로 설정 합 니 다.이러한 첫 번 째 방법 에는 fnt 파일 에 포 함 된 정보 가 기본적으로 이'그림 집합'에 포함 되 어 있다.마찬가지 로 Editor 스 크 립 트 를 써 서 이 정 보 를 CustomFont 에 기록 하고 수 동 으로 만 들 지 않 아 도 됩 니 다.

using UnityEngine;
using UnityEditor;
using System.IO;
 
public class CreateFont : EditorWindow
{
 [MenuItem("Tools/    (sprite)")]
 public static void Open()
 {
  GetWindow<CreateFont>("    ");
 }
 
 private Texture2D tex;
 private string fontName;
 private string fontPath;
 
 private void OnGUI()
 {
  GUILayout.BeginVertical();
 
  GUILayout.BeginHorizontal();
  GUILayout.Label("    :");
  tex = (Texture2D)EditorGUILayout.ObjectField(tex, typeof(Texture2D), true);
  GUILayout.EndHorizontal();
 
  GUILayout.BeginHorizontal();
  GUILayout.Label("    :");
  fontName = EditorGUILayout.TextField(fontName);
  GUILayout.EndHorizontal();
 
  GUILayout.BeginHorizontal();
  if (GUILayout.Button(string.IsNullOrEmpty(fontPath) ? "    " : fontPath))
  {
   fontPath = EditorUtility.OpenFolderPanel("    ", Application.dataPath, "");
   if (string.IsNullOrEmpty(fontPath))
   {
    Debug.Log("      ");
   }
   else
   {
    fontPath = fontPath.Replace(Application.dataPath, "") + "/";
   }
  }
  GUILayout.EndHorizontal();
 
  GUILayout.BeginHorizontal();
  if (GUILayout.Button("  "))
  {
   Create();
  }
  GUILayout.EndHorizontal();
 
  GUILayout.EndVertical();
 }
 
 private void Create()
 {
  if (tex == null)
  {
   Debug.LogWarning("    ,    !");
   return;
  }
 
  if (string.IsNullOrEmpty(fontPath))
  {
   Debug.LogWarning("      !");
   return;
  }
  if (fontName == null)
  {
   Debug.LogWarning("    ,      !");
   return;
  }
  else
  {
   if (File.Exists(Application.dataPath + fontPath + fontName + ".fontsettings"))
   {
    Debug.LogError("    ,         ");
    return;
   }
   if (File.Exists(Application.dataPath + fontPath + fontName + ".mat"))
   {
    Debug.LogError("    ,           ");
    return;
   }
  }
 
  string selectionPath = AssetDatabase.GetAssetPath(tex);
  if (selectionPath.Contains("/Resources/"))
  {
   string selectionExt = Path.GetExtension(selectionPath);
   if (selectionExt.Length == 0)
   {
    Debug.LogError("    !");
    return;
   }
   
   string fontPathName = fontPath + fontName + ".fontsettings";
   string matPathName = fontPath + fontName + ".mat";
   float lineSpace = 0.1f;
   //string loadPath = selectionPath.Remove(selectionPath.Length - selectionExt.Length).Replace("Assets/Resources/", "");
   string loadPath = selectionPath.Replace(selectionExt, "").Substring(selectionPath.IndexOf("/Resources/") + "/Resources/".Length);
   Sprite[] sprites = Resources.LoadAll<Sprite>(loadPath);
   if (sprites.Length > 0)
   {
    Material mat = new Material(Shader.Find("GUI/Text Shader"));
    mat.SetTexture("_MainTex", tex);
    Font m_myFont = new Font();
    m_myFont.material = mat;
    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();
     try
     {
      info.index = System.Convert.ToInt32(spr.name);
     }
     catch
     {
      Debug.LogError("    ,Sprite    !");
      return;
     }
     Rect rect = spr.rect;
     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;
     }
     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;
    }
    AssetDatabase.CreateAsset(mat, "Assets" + matPathName);
    AssetDatabase.CreateAsset(m_myFont, "Assets" + fontPathName);
    m_myFont.characterInfo = characterInfo;
    EditorUtility.SetDirty(m_myFont);
    AssetDatabase.SaveAssets();
    AssetDatabase.Refresh();//    
    Debug.Log("      ");
 
   }
   else
   {
    Debug.LogError("    !");
   }
  }
  else
  {
   Debug.LogError("    ,       Resources    !");
  }
 }
}
이 각본 은 어떤 박문 을 참고 하 였 는데,시간 이 지나 서 정말 찾 을 수 없다.
원 리 는 첫 번 째 방법 과 마찬가지 로 세부 적 인 계산 에 약간의 차이 가 있 을 뿐이다.사용 하기는 여전히 간단 하 다.

대동소이 한 두 가지 방법 은 개인 적 으로 두 번 째 방법 을 더 좋아한다.별도의 소프트웨어 를 사용 하지 않 고 원 클릭 으로 해결 하면 기본적으로 미술 아동 화 에 버 려 서 만 들 수 있다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기