Last active
July 14, 2016 05:38
-
-
Save exawon/324946a291bbf72fb493 to your computer and use it in GitHub Desktop.
Bitmap Font Importer for Unity
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://forum.unity3d.com/threads/unity-4-6-bitmap-font.265209/ | |
using UnityEngine; | |
using UnityEditor; | |
using System.IO; | |
using System.Xml; | |
using System.Collections.Generic; | |
#if BITMAP_FONT_ZIP | |
// https://dotnetzip.codeplex.com/ | |
using Ionic.Zip; | |
#endif | |
public class BitmapFontImporter : AssetPostprocessor | |
{ | |
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) | |
{ | |
foreach (string asset in importedAssets) | |
{ | |
if (asset.EndsWith(".fnt")) | |
{ | |
DoImport(asset, IsLtrExists(asset)); | |
} | |
#if BITMAP_FONT_ZIP | |
else if (asset.EndsWith(".zip") && IsLtrExists(asset)) | |
{ | |
DoUnzip(asset); | |
} | |
#endif | |
} | |
} | |
static bool IsLtrExists(string path) | |
{ | |
// http://kvazars.com/littera/ | |
var ltrPath = Path.ChangeExtension(path, ".ltr"); | |
return (AssetDatabase.LoadMainAssetAtPath(ltrPath) != null); | |
} | |
#if BITMAP_FONT_ZIP | |
static void DoUnzip(string zipPath) | |
{ | |
var fullPath = Application.dataPath + zipPath.Substring(6); | |
using (ZipFile zip = ZipFile.Read(fullPath)) | |
{ | |
var dirName = Path.GetDirectoryName(fullPath); | |
zip.ExtractAll(dirName, ExtractExistingFileAction.OverwriteSilently); | |
} | |
AssetDatabase.DeleteAsset(zipPath); | |
AssetDatabase.Refresh(); | |
} | |
#endif | |
static void DoImport(string xmlPath, bool removeSourceAsset) | |
{ | |
var fnt = AssetDatabase.LoadMainAssetAtPath(xmlPath) as TextAsset; | |
var xml = new XmlDocument(); | |
xml.LoadXml(fnt.text); | |
var info = xml.GetNode("info"); | |
var common = xml.GetNode("common"); | |
var directory = Path.GetDirectoryName(xmlPath); | |
var fontPath = string.Format("{0}/{1}.fontsettings", directory, info.GetString("face")); | |
var font = AssetDatabase.LoadMainAssetAtPath(fontPath) as Font; | |
if (font == null) | |
{ | |
font = new Font(); | |
AssetDatabase.CreateAsset(font, fontPath); | |
font.material = new Material(Shader.Find("GUI/Text Shader")); | |
font.material.name = "Font Material"; | |
AssetDatabase.AddObjectToAsset(font.material, font); | |
} | |
var so = new SerializedObject(font); | |
so.FindProperty("m_FontSize").floatValue = info.GetFloat("size"); | |
so.FindProperty("m_LineSpacing").floatValue = common.GetFloat("lineHeight"); | |
so.ApplyModifiedProperties(); | |
var page = xml.GetNode("pages").FirstChild; | |
var texPath = string.Format("{0}/{1}", directory, page.GetString("file")); | |
var texImporter = AssetImporter.GetAtPath(texPath) as TextureImporter; | |
texImporter.textureType = TextureImporterType.Sprite; | |
texImporter.compressionQuality = 100; | |
texImporter.mipmapEnabled = false; | |
texImporter.SaveAndReimport(); | |
var texture = AssetDatabase.LoadMainAssetAtPath(texPath) as Texture2D; | |
if (texture == null) | |
{ | |
Debug.LogErrorFormat(fnt, "{0}: not found '{1}'.", typeof(BitmapFontImporter), texPath); | |
return; | |
} | |
Object.DestroyImmediate(font.material.mainTexture, true); | |
font.material.mainTexture = Object.Instantiate<Texture2D>(texture); | |
font.material.mainTexture.name = "Font Texture"; | |
AssetDatabase.AddObjectToAsset(font.material.mainTexture, font); | |
int sw = common.GetInt("scaleW"); | |
int sh = common.GetInt("scaleH"); | |
var list = new List<CharacterInfo>(); | |
foreach (XmlNode ch in xml.GetNode("chars").ChildNodes) | |
{ | |
var chInfo = new CharacterInfo(); | |
chInfo.index = ch.GetInt("id"); | |
chInfo.advance = ch.GetInt("xadvance"); | |
chInfo.minX = ch.GetInt("xoffset"); | |
chInfo.minY = -ch.GetInt("yoffset"); | |
chInfo.maxX = chInfo.minX + ch.GetInt("width"); | |
chInfo.maxY = chInfo.minY - ch.GetInt("height"); | |
var r = new Rect(); | |
r.x = ch.GetFloat("x") / sw; | |
r.y = ch.GetFloat("y") / sh; | |
r.width = ch.GetFloat("width") / sw; | |
r.height = ch.GetFloat("height") / sh; | |
chInfo.uvTopLeft = new Vector2(r.xMin, 1.0f - r.yMax); | |
chInfo.uvBottomRight = new Vector2(r.xMax, 1.0f - r.yMin); | |
list.Add(chInfo); | |
} | |
font.characterInfo = list.ToArray(); | |
AssetDatabase.SaveAssets(); | |
if (removeSourceAsset) | |
{ | |
AssetDatabase.DeleteAsset(xmlPath); | |
AssetDatabase.DeleteAsset(texPath); | |
} | |
} | |
} | |
public static class XmlNodeExtension | |
{ | |
public static XmlNode GetNode(this XmlDocument xml, string tag, int index = 0) | |
{ | |
return xml.GetElementsByTagName(tag)[index]; | |
} | |
public static string GetString(this XmlNode node, string name) | |
{ | |
return node.Attributes.GetNamedItem(name).InnerText; | |
} | |
public static int GetInt(this XmlNode node, string name) | |
{ | |
return int.Parse(GetString(node, name)); | |
} | |
public static float GetFloat(this XmlNode node, string name) | |
{ | |
return float.Parse(GetString(node, name)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment