Растровые шрифты в Unity3D

Небольшая заметка-урок о том, как создать свой растровый шрифт и использовать его в Unity3D.

Данная заметка едва ли будет интересной и полезной для тех, кто с Unity «выпивал на брудершафт». Но для новичков, таких как я — это очень полезный и важный материал.

Чем глубже я знакомлюсь с Unity и пытаюсь его понять, тем больше я не понимаю его, и отрицательных эмоций в отношении Unity становится все больше и больше. Но, пожалуй, я сейчас не буду ныть о том, какой Unity плохой и сколько нужно времени и сил, чтобы постоянно доделывать недостающий функционал. Может быть позже, когда чаша негодования будет переполнена — я обязательно напишу об этом отдельно.

Сегодня я хочу рассказать лишь о маленькой части недостающего функционала: нативной поддержке растровых шрифтов в стандартном GUI Unity. Конечно же, поддержка таковых имеется! Но, как всегда, внезапно оказалось, что нет определенного решения для создания внедрения растровых шрифтов в Unity.

Введение в суть

В новом GUI Unity, который появился сравнительно не давно, есть такое понятие как Canvas — собственно это некоторое плоское пространство, в пределах которого рисуются любые GUI элементы. Среди этих элементов есть и текстовое поле — тут все просто и понятно. У этого текстового поля все как у любых других текстовых полей: шрифт, размер, выравнивание и другие замечательные настройки, которые позволяют настроить текст на свой вкус и цвет.

Но когда дело доходит до выбора шрифта — оказывается, что доступен всего лишь один стандартный шрифт «Arial», а где же все остальные шрифты, которые установлены в нашей системе?

Дело тут в том, что мы работаем с движком, который рендерит картинку аппаратно, а видео карты, как мы знаем, не умеют рисовать вектор — чем по сути является любой шрифт. Конечно, можно вектор преобразовать в полигоны и рисовать их, как 3д картинку (как настоящий вектор), но в рамках текста — это будет достаточно дорогой операцией. То есть, становится очевидно: тот единственный шрифт «Arial», что доступен по умолчанию — это не что иное, как растровый шрифт оригинального «Arial» шрифта. ? далее возникает лишь один вопрос, как сделать свой растровый шрифт?

Суровая реальность

Естественно, первое о чем я подумал: с таким большим количеством разработчиков на Unity и не только — все эти проблемы с генерацией шрифтов, это как слону дробина! Должно же быть готовое решение!

? вот оно решение: Bitmap Font Tools — всего за $39.99! Плати и наслаждайся!

Если посмотреть промо-видео к данному расширению — то выглядит все так, как я и хотел бы видеть, но не платя лишние $40 стороннему разработчику, а из коробки, прямо в Unity — как встроенная возможность!

? ценник на расширение как бы сразу намекнул — хочешь сэкономить время и не лезть в глубокие анналы, заплати и спи спокойно! Но, я, как вы знаете — я простых путей не ищу.

Есть, конечно, расширения для импорта шрифтов и по дешевле и по дороже. Потом я нашел и вовсе бесплатное, но было уже слишком поздно! Вызов принят.

А что-же генераторы шрифтов, неужели они не могут сделать шрифт сразу в необходимом формате для Unity!? К сожалению, не могут. Политика разработчиков генераторов шрифтов такова, что движки появляются и исчезают постоянно, а поддерживать формат каждого из них — это не простая задача, требующая определенных трудозотрат. Поэтому разработчики генераторов шрифтов (особенно бесплатных генераторов шрифтов), предпочитают поддерживать только базовые форматы (стандарты) — это легко и надежно. А разработчики движков, уж будьте добры, сами напишите импортер из базового формата в свой формат шрифта. Все просто и логично!

Но с разработчиками Unity что-то явно не так, раз они решили оставить решение этой базовой задачи на усмотрение своих пользователей. ? это при такой-то цене на движок!?

Погружение в технические тонкости

Что же, раз уж разработчики Unity оставили решение этой задачи на наше усмотрение, тогда будет весьма полезно разобраться в матчасти этого вопроса. Хотя бы ради того, чтобы понимать, за что мы должны заплатить в очередной раз свои кровные, покупая очередное расширение для Unity от сторонних разработчиков.

К сожалению, материала по этому вопросу оказалось не так много, как хотелось бы. А из материалов на русском языке, мне попалась только одна статья: «Custom font в Unity3D»

Внимательно изучив статью, моя рука стремительно протянулась к лицу, дабы воссоздать емоджи «рукалицо» в реальной жизни!

Если вы еще не знакомы с выше обозначенной статьей, то не спешите её читать, я перескажу её суть: в статье достаточно подробно рассказывается, как создать свой растровый шрифт и как замаппить его в Unity. То есть, связать отдельные регионы на изображении с отдельными символами и/или их кодами. Вся эта процедура напоминает текстурирование какой-нибудь модели, только текстурные координаты высчитываются в «уме» и вбиваются вручную в нужные поля. Все это выглядит терпимо и доступно если речь идет о 10 символах, а если нужно сделать 90 символов? А если нужно добавить поддержку нового языка с новыми символами!? В общем, никогда не делайте так, как рассказано в статье! Пусть эта статья будет лишь настольным пособием о том, как это все работает и не более того.

В итоге, очевидно: нужно брать уже готовый импортер шрифтов! Покупать пару скриптов за весьма ощутимые деньги — не хочется, а бесплатные могут устареть или иметь проблемы с поддержкой новых версий Unity, поэтому на них полагаться немного боязно. Если честно, то мне вообще боязно тащить все подряд расширения и библиотеки в свой проект — чем их больше в проекте, тем страшнее, что с каждым новым обновлением Unity они могут, и будут ломаться и отваливаться.

В общем, я уже зашел слишком далеко и пути обратно нет. Время написать свой импортер растровых шрифтов!

?мпортер Bitmap шрифтов для Unity

? так, изучив статью на Хабре и исходные данные из генераторов шрифтов, стало понятно, что нужно просто перебрать полученные данные и построить на их основе шрифт в формате Unity. Сам шрифт Unity хранится в виде бинарных данных, и чтобы корректно его создать и использовать, следует работать с ним прямо в редакторе Unity. Проще говоря, нужен некоторый скрипт, который сможет прочитать текстовый файл, и записать эти данные в объект шрифта Unity.

Ранее я работал с форматами шрифтов Starling — этот формат представляет собой обычный XML файл, в котором записана вся информация о символах и их расположениях на картинке. У Unity тоже есть такой формат данных, который представляет собой текстовый файл с точно такими же данными, как и у Starling, разница лишь в том, что этот текстовый файл не содержит XML тэгов. Я так и не нашел информации о том, как называется этот формат, везде он обозначался, как текстовый формат Unity, или что-то вроде этого.

Вначале я хотел сделать импортер шрифтов для формата Starling, но потом подумал: раз уж я работаю с Unity, то нужно сделать импорт из формата данных для Unity, и не вмешивать сюда Starling. Хотя, признаюсь, из формата Starling было бы проще импортировать, так как имеются нативные инструменты для чтения и парсинга XML данных. ? вот опять же — зачем придумывать какой-то новый формат данных, пусть и на базе обычного текста, когда можно было бы использовать уже какой-то готовый формат!? В общем, Unity — это находка для любителей копаться в редакторах, писать расширения и всячески настраивать среду разработки под себя.

В итоге я решил не рассказывать и не показывать фрагменты кода о том, как написать свой импортер шрифтов для Unity, а просто выкладываю то, что у меня получилось и предлагаю вам воспользоваться уже готовым решением.

 

Преимущества:

  • Всего лишь один скрипт и никакой лишней шелухи, лишних пунктов меню со ссылками и т.п.
  • Простой и понятный код.
  • Простое использование.
  • Никаких ограничений и абсолютно бесплатно!

Как использовать?

Теперь осталось разобраться только с тем, как создать свой растровый шрифт и как импортировать его в Unity.

Для генерации шрифтов существует множество платных и бесплатных программ:

  • Littera — бесплатный генератор шрифтов, позволяющий настраивать внешний стиль. Работает онлайн, не требует установки. Удобно если нужно сгенерировать какой-нибудь простой шрифт с простыми эффектами.
  • Glyph Designer — платный генератор шрифтов, позволяющий настраивать внешний стиль, вроде как имеет чуть больше возможностей и настроек. Требует установки. Доступен для Mac и Win.
  • ShoeBox — бесплатный, не умеет генерировать шрифты, но зато ловко разрезает картинку с буквами и готовит из нее растровый шрифт. Требует установленный Adobe AIR.
  • А так же, подойдут любые любые другие генераторы шрифтов, которые умеют выгонять данные в текстовом формате для Unity.

     

Я люблю делать шрифты руками — так как это позволяет более точно получать визуальный стиль, отвечающий моим предпочтениям, поэтому я остановился на ShoeBox. Вообще ShoeBox незаменимая программа для разработчиков игр — она позволяет автоматизировать решение многих рутинных задач, с которыми часто приходится сталкиваться. Но подробнее об этом вы можете узнать на официальном сайте.

Шаг 1: Первое, что нужно сделать — это установить и запустить программу. После запуска ShoeBox переходим на вкладку GUI, нажимаем правой кнопкой мыши на «Bitmap Font» — откроются базовые настройки, в поле «Template» сразу следует выбрать формат «FNT Unity». Закрываем окно, применяя изменения. После чего нажимаем и удерживаем некоторое время левую кнопку мыши на иконке «Bitmap Font», до появления сообщение «Copied Text to Clipboard!». Это значит, что программа скопировала в буфер обмена текст, представляющий из себя набор символов, которые мы хотим растеризировать.

В расширенных настройках для «Bitmap Font» в поле «Txt Chars» можно задать желаемый набор символов для растерзании — удалив лишние или добавив новые, например русские.

Шаг 2: Когда необходимый набор символов оказался в буфере обмена, нужно перейти в свой любимый растровый редактор, например в Photoshop, создать там текстовое поле, настроить его визуальный стиль и вставить содержимое буфера обмена.

Скорее всего ваше текстовое поле растянется до таких размеров, что окажется за пределами холста. Нужно увеличить холст, чтобы текстовое поле помещалось в него целиком. ? после этого сохранить получившееся изображение в *.png.

(Важно! ShoeBox не умеет распознавать буквы на картинке, поэтому буквы должны быть в одну строку. Так же важно убедиться, что ни один символ не пропущен, например, если в используемом шрифте каких-то символов не хватает. Если в используемом шрифте отсутствуют некоторые символы, то их следует исключить из строки «Txt Chars» в настройках ShoeBox, либо дорисовать вручную, соблюдая порядок. В противном случае, отсутствующие символы нарушат распознание картинки в ShoeBox, и программа не свяжет распознанные регионы с заданными символами в правильном порядке, и как результат, в место нужных символов будут отображаться совсем другие.)

Шаг 3: После того, как исходный *.png готов, просто перетягиваем его на иконку «Bitmap Font» в ShoeBox. В зависимости от формата и размера графического файла может понадобиться разное время, чтобы ShoeBox его распознал, разрезал и обработал. Но когда работа будет проделана перед вами откроется окно с результатом.

Далее, следует убедиться, что все символы связанны правильно, а так же настроить кернинг и высоту линии — это все делается индивидуально на ваш вкус и цвет в настройках. Когда все будет готово, нажимаем «Save Font» и получаем два новых файла: пережатая картинка с буквами и файл с данными о расположении регионов-букв на этой картинке.

Шаг 4: Перемещаем полученные файлы в проект Unity в любую удобную папку подпапки Assets.

А скрипт AntFontImporter.cs перемещаем в папку Libraries или в любую другую папку, где у вас находятся сторонние вспомогательные скрипты.

Шаг 5: После того, как скрипт AntFontImporter и шрифт добавлены в Unity проект, нужно выделить файл данных шрифта, вызвать к нему контекстное меню и выбрать пункт «Convert FNT to Font». После успешной конвертации шрифта в этой же папке появятся два новых файла: материал шрифта и сам шрифт. Но если что-то пошло не так, то проверьте лог консоли Unity на предмет шагов конвертации шрифта и возможных ошибок.

Шаг 6: Теперь остается только создать текстовое поле, назначить полученный шрифт и материал для этого поля, установить другие важные настройки, например цвет и проверить результат.

? напоследок несколько советов:

Совет #1: Не используйте Size для определения размеров шрифта, вместо этого следует использовать Scale.

Совет #2: ?спользуйте Scale для текста, только если вы хотите получить какие-либо эффекты. Но если вам нужны тексты разных размеров, то следует заготовить несколько разных растровых шрифтов с заранее заданными размерами. Такой подход положительно скажется на производительности и на качестве отображения самих текстов.

Заключение

В последнее время Unity все чаще и чаще стал преподносить мне неприятные сюрпризы вроде того, что я описал в этой статье. ? вместо того, чтобы заниматься разработкой игры, мне приходится решать какие-то технические проблемы Unity или отсутствие какого-то базового функционала.

Помните месяц назад я обещал вернуться к еженедельным записям о ходе разработки!? Так вот, этого не получилось не потому, что лето продолжается, а потому, что я занимаюсь изучением подводных камней в Unity и изобретением костылей для того функционала, который в Unity должен быть в базе, но его нет!

В итоге, все немного пошло не так. ? я выбился из графика работы по игре и теперь мне приходится усиленными темпами догонять план работ, при этом жертвуя дневниками разработки. Собственно и рассказать то пока особо не о чем, так как разработка игры застопорилась.

Конечно, многие проблемы, с которыми я столкнулся — легко решаются за счет покупки сторонних ассетов/плагинов, но в бюджет разработки я не закладывал столь большие траты на тот функционал, который ожидал получить в комплекте с Unity, поэтому теперь приходится выкручиваться по разному.