Как-то при подготовке своего проекта в Unity3d у меня возникла необходимость использовать Bitmap font (он же растровый шрифт). Я очень обрадовался, когда обнаружил в Unity инструменты для создания такого шрифта. Но спустя некоторое время понял, что процедура эта отнюдь нетривиальна из-за отсутствия какой-либо документации на этот счёт.
Эта статья о том, как собрать в Unity готовый к использованию Custom Bitmap Font. Урок довольно подробный и затрагивает работу в Photoshop. Заинтересовавшихся прошу под кат.
Как объясняет wiki, растровый шрифт — это фактически набор растровых изображений всех используемых символов. То есть, в первую очередь нам понадобится текстура, содержащая изображения всех нужных нам символов. В этом примере я ограничусь только цифрами и парочкой вспомогательных знаков, однако использовать такую технику можно на любое количество глифов.
Наш шрифт будет содержать 14 символов: цифры от нуля до девяти, знаки "+", "-", точка, разделяющая дробную и целую части и пробел. Так же оставим парочку резервных мест для символов, которые мы, возможно, захотим добавить в будущем. Итого 16 слотов на текстуре.
Наиболее оптимальным образом расположить эти 16 слотов на текстуре можно таким способом: использовать 4 столбца и 4 строки
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/af5/360/866/af536086631be4ba4625395862cc0b8b.png)
Для подготовки примера я использовал Photoshop, и по ходу урока я так же буду давать некоторые пояснения к своим дейсвиям в нём. Итак, открываем редактор изображений и создаём новый документ, размером 400 на 400 пикселей. Рзамер текстуры на данном этапе особо не критичен, главное, чтобы он был не слишком маленьким. Конечный размер текстуры мы выставим уже в Unity в самом конце урока.
Для удобства работы я советую включить отображение линейки, сетки и направляющих (ruler, grid и guides). Хоткей для отображения сетки Ctrl+' для направляющих Ctrl+; для линейки Ctrl+R. Для создания направляющей просто перетащите её с линейкина документ. Настройки всех этих помощников находятся в меню Edit -> Preferences -> Units & Rulers
Далее нам предстоит заполнить текстуру содержанием в виде, собственно, символов. В качестве основы своего растрового шрифта я использовал бесплатный шрифт Unispace. Вызываем инструмент «Text» горячей клавишей Shift+T и вводим наш первый глиф. Все символы должны быть точно позиционированны по центру каждого из 16 слотов (тут нам пригодится вспомогательная сетка). После ввода первого символа (в нашем случае это ноль) жмём Enter для подтверждения ввода. Чтобы правильно позиционировать слой, нажатием клавиш Ctrl+T вызываем инструмент «Transform» и перемещаем слой в нужное место, руководствуясь вспомогательной сеткой.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/7bf/a25/231/7bfa2523121c1c1e3edec3b791de48ab.png)
Проделываем эту нехитрую операцию со всеми нужными нам символами и — вуаля!
Следующим этапом мы объединим все получившиеся слои с цифрами и знаками в один общий слой. Для этого выделим их на панели Layers и нажмём Ctrl+E. Главное случайно не зацепить слой фона, ведь тогда пропадёт вся информация о прозрачности. После этого начинается самая интересная и творческая часть работы. Настраивание эффектов слоя по вкусу. Подробно здесь я не буду её описывать, каждый решит сам, что ему нравится и сделает на свой лад. Что получилось у меня, можно увидеть на картинке ниже.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/542/59e/49e/54259e49ee20dfdd6d167e7474181d70.png)
Итак, на данный момент мы имеем два слоя: наши цифры со знаками и белый слой фона. После того, как мы настроили все нужные нам эффекты, сделаем резервную копию слоя и приступим к следующему этапу: создание альфа-канала.
В альфа-канале будет храниться информация о прозрачности. Черные пиксели отвечают за полную прозрачность, белые — наоборот. Оттенки серого же создают эффект различных степеней полупрозрачности. В моём случае вокруг символов имеется мягкая черная тень, которую я хотел бы видеть плавно затухающей по мере распространения в стороны от символов. Чтобы добиться такого эффекта, мы как раз и будем использовать полутона в альфа-канале.
Свежепродублированный слой станет основной нашего альфа-канала. Для начала нам надо запечь все его эффекты, то есть растеризовать слой. Для этого я обычно создаю новый пустой слой, выделяю его и слой, с которым я сейчас работаю — и объединяю их в один (Ctrl+E).
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/f10/48a/ba6/f1048aba6eb109ffd1922094931e7b2f.png)
У нас получился растеризированный слой с информацией о прозрачности. Теперь осталось только перенести эту информацию в альфа-канал. Для этого, удерживая Ctrl, щелкаем по ионке слоя в панели Layers — получая выделение по маске прозрачности, и, на панели Channels создаём новый канал, опять-таки удерживая Ctrl. Кнопка создания нового канала находится справа внизу панели возле кнопки удаление канала, с корзинкой. Получившийся канал оказался инвертированным — не беда. Комбинацией Ctrl+I восстанавливаем нормальное положение вещей.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/6a7/35f/1ac/6a735f1ac6a87ec6d5ce78ed806af14d.png)
Альфа-канал готов. Текстура, в общем-то, тоже. За исключением того, что белый слой фона мешает правильному отображению тени вокруг символов. Я раскрасил его в цвет тени.
Сохраняем текстуру в любимый формат, поддерживающий альфа-канал (я использую TGA-32bit) и переходим к следующему этапу.
Импортируем текстуру в Unity3d. Для этого в панели Project находим папку Assets и из контекстного меню вызываем Import New Asset… Находим файл с нашей текстурой. Готово.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/449/d55/3eb/449d553ebd6a3b225401e3ed4479d4cd.png)
Настройки текстуры довольно очевидны, и я не стану подробно расписывать их. Упомяну лишь, что вам необходимо выставить вменяемый размер текстуры. В нашем случае вполне подойдёт 256x256 px.
Далее в том же контекстном меню создаём новый материал и ассет шрифта (Create -> Material, Create -> Custom Font). В настройках материала выбираем только что импортированную текстуру. Также материал должен поддерживать прозрачность. Поэтому тип материала мы подбираем соответствующий: Transparent/Diffuse.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/547/dd1/080/547dd1080ccc0cd9021bf3861dc2c36b.png)
Наконец, мы подошли к самой сути урока. У нас имеется настроенный материал с красивенькой текстурой, и теперь надо как-то собрать из него готовый к использованию в Unity растровый шрифт.
По непонятной причине инструмент создания растрового шрифта в Unity сделан крайне неудобно. Впридачу, никакой документации по нему в сети найти не удалось. Всё, что мы имеем, это невнятная панель с настройками:
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/463/d09/548/463d09548e0aca55986bd9cbb4c4894f.png)
Проковырявшись в ней битых несколько часов, мне все же удалось распознать большинство параметров, которых хватает для создания шрифта.
Ascii Start Offset — целое число, отвечающее за сдвиг таблицы Ascii-кода. Пример: устанавливаем значение 10, и теперь доступ к символу «A» с кодом 65 можно получить через код 75.
Kerning — интервал между буквами.
Line Spacing — расстояние между строками текста.
Default Material — материал с текстурой шрифта. Мы его уже создали.
Character Rects — массив настроек маппинга для каждого символа.
Именно Character Rects нам интересней всего.
Size — размер массива (количество символов в шрифте).
Element x — элемент массива Character Rects с настройками конкретного символа.
Index — Ascii-код символа с учётом Ascii Start Offset.
UV — координаты и размеры символа на текстуре.
X, Y, W, H — координаты нижнего левого угла участка текстуры с символом, а так же ширина и высота этого участка.
Здесь необходимо сделать небольшое отступление в теорию маппига, в спойлере имеется краткое наглядное пособие.
Vert — координаты и размеры полигона, на который будет маппиться символ
X, Y, W, H — координаты нижнего левого угла полигона с символом, а так же ширина и высота этого полигона. В общем случае x и y выставляем в 0, w и h длина и ширина полигона, причем h отрицательное число. Не спрашивайте, почему, я так сам и не понял.
Width — что-то вроде межбуквенного интервала для конкретного символа.
Flipped — поворачивает текстуру на 90 градусов относительно полигона (может использоваться для вертикальных шрифтов).
Итак, основные параметры должны быть ясны. Приступим к маппингу наших циферок. Для начала взглянем на таблицу Ascii-кодов.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/837/7ea/2f8/8377ea2f8dd59758629c8c55865537c9.png)
Как несложно заметить, каждому символу соответствует уникальный Ascii-код. Наприер, код 43 принадлежит знаку плюс. И вот теперь мы приступаем к тяжелой муторной работе по вписыванию координат в соответствующие поля. Ниже дана картинка, на которой показано, как были замапленны знаки плюс и минус.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/030/ef5/639/030ef5639269e8075d5f940b22e2dc3f.png)
После того, как все символы будут замапленны, можно поздравить вас с выполнением очень трудной задачи: шрифт готов и теперь его можно использовать!
Создадим в сцене проекта пустой объект. Назначим ему компонент «TextMesh» и выберем в настройках наш шрифт.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/be7/97e/173/be797e173a31d197d433208db3d0ce13.png)
Красота!
Создание растровых шрифтов в Unity — очень непростая, но интересная работа. Хочется верить, что, пройдя этот урок, вы узнали для себя что-то новое и полезное. Отсутствие такого описания в своё время сильно тормознуло продвижение моего проекта. И я надеюсь, что этот текст поможет сэкономить кучу времени всем, кому однажды понадобится создать кастомный фонт в Unity.
Эта статья о том, как собрать в Unity готовый к использованию Custom Bitmap Font. Урок довольно подробный и затрагивает работу в Photoshop. Заинтересовавшихся прошу под кат.
Введение
Как объясняет wiki, растровый шрифт — это фактически набор растровых изображений всех используемых символов. То есть, в первую очередь нам понадобится текстура, содержащая изображения всех нужных нам символов. В этом примере я ограничусь только цифрами и парочкой вспомогательных знаков, однако использовать такую технику можно на любое количество глифов.
Подготовка текстуры
Наш шрифт будет содержать 14 символов: цифры от нуля до девяти, знаки "+", "-", точка, разделяющая дробную и целую части и пробел. Так же оставим парочку резервных мест для символов, которые мы, возможно, захотим добавить в будущем. Итого 16 слотов на текстуре.
Наиболее оптимальным образом расположить эти 16 слотов на текстуре можно таким способом: использовать 4 столбца и 4 строки
![](https://habrastorage.org/getpro/habr/post_images/af5/360/866/af536086631be4ba4625395862cc0b8b.png)
Для подготовки примера я использовал Photoshop, и по ходу урока я так же буду давать некоторые пояснения к своим дейсвиям в нём. Итак, открываем редактор изображений и создаём новый документ, размером 400 на 400 пикселей. Рзамер текстуры на данном этапе особо не критичен, главное, чтобы он был не слишком маленьким. Конечный размер текстуры мы выставим уже в Unity в самом конце урока.
Для удобства работы я советую включить отображение линейки, сетки и направляющих (ruler, grid и guides). Хоткей для отображения сетки Ctrl+' для направляющих Ctrl+; для линейки Ctrl+R. Для создания направляющей просто перетащите её с линейкина документ. Настройки всех этих помощников находятся в меню Edit -> Preferences -> Units & Rulers
Далее нам предстоит заполнить текстуру содержанием в виде, собственно, символов. В качестве основы своего растрового шрифта я использовал бесплатный шрифт Unispace. Вызываем инструмент «Text» горячей клавишей Shift+T и вводим наш первый глиф. Все символы должны быть точно позиционированны по центру каждого из 16 слотов (тут нам пригодится вспомогательная сетка). После ввода первого символа (в нашем случае это ноль) жмём Enter для подтверждения ввода. Чтобы правильно позиционировать слой, нажатием клавиш Ctrl+T вызываем инструмент «Transform» и перемещаем слой в нужное место, руководствуясь вспомогательной сеткой.
![](https://habrastorage.org/getpro/habr/post_images/7bf/a25/231/7bfa2523121c1c1e3edec3b791de48ab.png)
Проделываем эту нехитрую операцию со всеми нужными нам символами и — вуаля!
Следующим этапом мы объединим все получившиеся слои с цифрами и знаками в один общий слой. Для этого выделим их на панели Layers и нажмём Ctrl+E. Главное случайно не зацепить слой фона, ведь тогда пропадёт вся информация о прозрачности. После этого начинается самая интересная и творческая часть работы. Настраивание эффектов слоя по вкусу. Подробно здесь я не буду её описывать, каждый решит сам, что ему нравится и сделает на свой лад. Что получилось у меня, можно увидеть на картинке ниже.
![](https://habrastorage.org/getpro/habr/post_images/542/59e/49e/54259e49ee20dfdd6d167e7474181d70.png)
Итак, на данный момент мы имеем два слоя: наши цифры со знаками и белый слой фона. После того, как мы настроили все нужные нам эффекты, сделаем резервную копию слоя и приступим к следующему этапу: создание альфа-канала.
В альфа-канале будет храниться информация о прозрачности. Черные пиксели отвечают за полную прозрачность, белые — наоборот. Оттенки серого же создают эффект различных степеней полупрозрачности. В моём случае вокруг символов имеется мягкая черная тень, которую я хотел бы видеть плавно затухающей по мере распространения в стороны от символов. Чтобы добиться такого эффекта, мы как раз и будем использовать полутона в альфа-канале.
Свежепродублированный слой станет основной нашего альфа-канала. Для начала нам надо запечь все его эффекты, то есть растеризовать слой. Для этого я обычно создаю новый пустой слой, выделяю его и слой, с которым я сейчас работаю — и объединяю их в один (Ctrl+E).
![](https://habrastorage.org/getpro/habr/post_images/f10/48a/ba6/f1048aba6eb109ffd1922094931e7b2f.png)
У нас получился растеризированный слой с информацией о прозрачности. Теперь осталось только перенести эту информацию в альфа-канал. Для этого, удерживая Ctrl, щелкаем по ионке слоя в панели Layers — получая выделение по маске прозрачности, и, на панели Channels создаём новый канал, опять-таки удерживая Ctrl. Кнопка создания нового канала находится справа внизу панели возле кнопки удаление канала, с корзинкой. Получившийся канал оказался инвертированным — не беда. Комбинацией Ctrl+I восстанавливаем нормальное положение вещей.
![](https://habrastorage.org/getpro/habr/post_images/6a7/35f/1ac/6a735f1ac6a87ec6d5ce78ed806af14d.png)
Альфа-канал готов. Текстура, в общем-то, тоже. За исключением того, что белый слой фона мешает правильному отображению тени вокруг символов. Я раскрасил его в цвет тени.
Сохраняем текстуру в любимый формат, поддерживающий альфа-канал (я использую TGA-32bit) и переходим к следующему этапу.
Подготовка к созданию шрифта в Unity
Импортируем текстуру в Unity3d. Для этого в панели Project находим папку Assets и из контекстного меню вызываем Import New Asset… Находим файл с нашей текстурой. Готово.
![](https://habrastorage.org/getpro/habr/post_images/449/d55/3eb/449d553ebd6a3b225401e3ed4479d4cd.png)
Настройки текстуры довольно очевидны, и я не стану подробно расписывать их. Упомяну лишь, что вам необходимо выставить вменяемый размер текстуры. В нашем случае вполне подойдёт 256x256 px.
Далее в том же контекстном меню создаём новый материал и ассет шрифта (Create -> Material, Create -> Custom Font). В настройках материала выбираем только что импортированную текстуру. Также материал должен поддерживать прозрачность. Поэтому тип материала мы подбираем соответствующий: Transparent/Diffuse.
![](https://habrastorage.org/getpro/habr/post_images/547/dd1/080/547dd1080ccc0cd9021bf3861dc2c36b.png)
Наконец, мы подошли к самой сути урока. У нас имеется настроенный материал с красивенькой текстурой, и теперь надо как-то собрать из него готовый к использованию в Unity растровый шрифт.
Растровый шрифт в Unity
По непонятной причине инструмент создания растрового шрифта в Unity сделан крайне неудобно. Впридачу, никакой документации по нему в сети найти не удалось. Всё, что мы имеем, это невнятная панель с настройками:
![](https://habrastorage.org/getpro/habr/post_images/463/d09/548/463d09548e0aca55986bd9cbb4c4894f.png)
Проковырявшись в ней битых несколько часов, мне все же удалось распознать большинство параметров, которых хватает для создания шрифта.
Ascii Start Offset — целое число, отвечающее за сдвиг таблицы Ascii-кода. Пример: устанавливаем значение 10, и теперь доступ к символу «A» с кодом 65 можно получить через код 75.
Kerning — интервал между буквами.
Line Spacing — расстояние между строками текста.
Default Material — материал с текстурой шрифта. Мы его уже создали.
Character Rects — массив настроек маппинга для каждого символа.
Именно Character Rects нам интересней всего.
Size — размер массива (количество символов в шрифте).
Element x — элемент массива Character Rects с настройками конкретного символа.
Index — Ascii-код символа с учётом Ascii Start Offset.
UV — координаты и размеры символа на текстуре.
X, Y, W, H — координаты нижнего левого угла участка текстуры с символом, а так же ширина и высота этого участка.
Здесь необходимо сделать небольшое отступление в теорию маппига, в спойлере имеется краткое наглядное пособие.
Краткая пояснялка в маппинг
Маппинг текстуры — процесс нанесения текстуры на полигональные поверхности в компьютерной графике.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/cfb/0a5/1fa/cfb0a51fa5e1f4e15cfd7d20dcce5907.png)
Текстурные координаты участка с цифрой пять будут такими:
![](https://habrastorage.org/getpro/habr/post_images/cfb/0a5/1fa/cfb0a51fa5e1f4e15cfd7d20dcce5907.png)
Текстурные координаты участка с цифрой пять будут такими:
X = 0.25, Y = 0.5, H = 025, W = 0.25
Vert — координаты и размеры полигона, на который будет маппиться символ
X, Y, W, H — координаты нижнего левого угла полигона с символом, а так же ширина и высота этого полигона. В общем случае x и y выставляем в 0, w и h длина и ширина полигона, причем h отрицательное число. Не спрашивайте, почему, я так сам и не понял.
Width — что-то вроде межбуквенного интервала для конкретного символа.
Flipped — поворачивает текстуру на 90 градусов относительно полигона (может использоваться для вертикальных шрифтов).
Итак, основные параметры должны быть ясны. Приступим к маппингу наших циферок. Для начала взглянем на таблицу Ascii-кодов.
![](https://habrastorage.org/getpro/habr/post_images/837/7ea/2f8/8377ea2f8dd59758629c8c55865537c9.png)
Как несложно заметить, каждому символу соответствует уникальный Ascii-код. Наприер, код 43 принадлежит знаку плюс. И вот теперь мы приступаем к тяжелой муторной работе по вписыванию координат в соответствующие поля. Ниже дана картинка, на которой показано, как были замапленны знаки плюс и минус.
![](https://habrastorage.org/getpro/habr/post_images/030/ef5/639/030ef5639269e8075d5f940b22e2dc3f.png)
После того, как все символы будут замапленны, можно поздравить вас с выполнением очень трудной задачи: шрифт готов и теперь его можно использовать!
Создадим в сцене проекта пустой объект. Назначим ему компонент «TextMesh» и выберем в настройках наш шрифт.
![](https://habrastorage.org/getpro/habr/post_images/be7/97e/173/be797e173a31d197d433208db3d0ce13.png)
Красота!
Послесловие
Создание растровых шрифтов в Unity — очень непростая, но интересная работа. Хочется верить, что, пройдя этот урок, вы узнали для себя что-то новое и полезное. Отсутствие такого описания в своё время сильно тормознуло продвижение моего проекта. И я надеюсь, что этот текст поможет сэкономить кучу времени всем, кому однажды понадобится создать кастомный фонт в Unity.