Unreal Engine - Разработка ч.16 - класс Actor - Форматирование сообщений отладки
Окей. Продолжаем. Сегодня разберемся как форматировать текст для лорнирования.
Я хочу вывести в аутпут лог дельтатайм сцены. Для этого нам снова открыть VS, найти наш Item и воспользоваться макросом UE_LOG:
Я хочу вывести в аутпут лог дельтатайм сцены. Для этого нам снова открыть VS, найти наш Item и воспользоваться макросом UE_LOG:
Пока что ничего нового. Я использовал Макрос UE_LOG в параметры я ввел Временную категорию логирования, Verbosity - Warning и, как обычно, использовал макрос TEXT() в параметры которого ввел литералы типа string. Чуть раньше мы говорили про Format и _VA_ARGS_ , что буквально означает что мы можем подавать в макрос сколько угодно аргументов, в свою очередь это означает что мы можем подать float переменную DeltaTime напрямую в UE_LOG, тем не менее UE_LOG должен знать как её использовать поэтому нам нужно указать как именно форматировать эту дату, для этого нам придется использовать определители формата.
DeltatTime имеет тип значения float, это означает что нам нужно показать где конкретно эта float будет отображаться в нашем логе. Это нужно сделать с помощью %f определителя формата, его нужно поставить где угодно в string для корректного отображения:
В таком случае UE_LOG заменит %f на значение DeltaTime, точне на первый аргумент после макроса TEXT. Давайте посмотрим как это сработает. Как обычно сохраняемся, делаем HotReload и:
В логе будет спамиться DeltaTime. Таким образом мы отобразили DeltaTime в аутпут логе используя определитель формата.
Эти определите формата берут своё начало из С++, хотя на самом деле они идут вообще из С, и они относятся к C функции printf. printf по сути своей работает так же как UE_LOG, он может брать в себя несколько параметров и может форматировать строку используя определители формата:
Эти определите формата берут своё начало из С++, хотя на самом деле они идут вообще из С, и они относятся к C функции printf. printf по сути своей работает так же как UE_LOG, он может брать в себя несколько параметров и может форматировать строку используя определители формата:
Источник находится вот тут. Как мы можем их использовать? Да в принципе все из списка, но в разработке игр чаще всего мы будем работать с простыми типами данных, такими как float, double и int.
Теперь когда мы разобрались как форматировать сообщения в логе давайте попробуем сделать то же самое с сообщениями на экране. Для начала я скопирую из Begin Play, наш GEngine пример в Tick:
Теперь когда мы разобрались как форматировать сообщения в логе давайте попробуем сделать то же самое с сообщениями на экране. Для начала я скопирую из Begin Play, наш GEngine пример в Tick:
Теперь мы будем выводить сообщение на экран каждый тик. Мы используем ключ 1, поэтому старые сообщения будут заменяться новыми и не будет спама на экране. Далее я хочу сделать так же как в UE_LOG, т.е чтобы с помощью TEXT() и определителя формата я мог подать значение переменной DeltaTime.
FString содержит в себе статическую функцию которая позволяет форматировать string. Другими словами мы можем создать объект типа FString прямо в теле if и задать ему значение равное набору символов с нужным нам форматом:
FString содержит в себе статическую функцию которая позволяет форматировать string. Другими словами мы можем создать объект типа FString прямо в теле if и задать ему значение равное набору символов с нужным нам форматом:
Я создал объект типа FString и присвоил ему имя Message. Далее я использовал FString и :: после чего VS сразу показал что Printf является очень популярным выбором в такого типа строке. Спасибо за помощь ею я точно воспользуюсь:
Printf содержит в себе конструктор который позволяет подать в него string и опционально аргументы в него. Давайте используем макрос TEXT() тут:
Мы по сути своей сделали то же самое что и раньше, только теперь у нас есть переменная типа FString которую мы можем использовать в функции ниже:
Сохраняемся, делаем HotReload и смотрим на результат:
Таким образом мы можем форматировать наш string в UE используя тип данных FString.
Ранее мы с вами уже разбирали стандартный string и то как он работает. В UE есть своя версия string и это FString. Хоть по сути своей это одно и то же, но в UE предпочтительней использовать не родные C++ типы данных которые Эпики любезно предоставили. Причина этому простая - кросс платформенная поддержка. Это может показать не очевидным но казалось бы одинаковые типы данных на разных платформах ведут себя совершенно по разному в совершенно не очевидных местах. Вы конечно можете себе родить таску по ловле очень странного бага на какой нить PS4, но лучше потратить это время на что нить полезное.
Вы спросите как я вообще узнал про то что существует Printf в FString. Тут нет никакой загадки. Мы можем перейти к описанию любого объекта используя встроенный функционал VS (да и любого редактора в целом) для этого на типе данных нужно нажать правой кнопкой мышки и выбрать один из двух вариантов:
Ранее мы с вами уже разбирали стандартный string и то как он работает. В UE есть своя версия string и это FString. Хоть по сути своей это одно и то же, но в UE предпочтительней использовать не родные C++ типы данных которые Эпики любезно предоставили. Причина этому простая - кросс платформенная поддержка. Это может показать не очевидным но казалось бы одинаковые типы данных на разных платформах ведут себя совершенно по разному в совершенно не очевидных местах. Вы конечно можете себе родить таску по ловле очень странного бага на какой нить PS4, но лучше потратить это время на что нить полезное.
Вы спросите как я вообще узнал про то что существует Printf в FString. Тут нет никакой загадки. Мы можем перейти к описанию любого объекта используя встроенный функционал VS (да и любого редактора в целом) для этого на типе данных нужно нажать правой кнопкой мышки и выбрать один из двух вариантов:
Так же можно нажать на CTRL и навести мышку на интересущий нас объект, он превратится в "гиперссылку" на которую можно нажать:
Внутри мы обнаружим ссылку на документацию:
В ней уже подробно расписано что есть в этом типе данных и как им пользоваться. Если вам лень её читать вы может почитать код прям внутри редактора, оно даже полезней будет. К примеру пролистав чуть ниже мы можем найти конструкторы класса с несколькими оверлодами для него:
Из них станет понятно что мы можем создать FString как без параметров вообще, и это будет пустой строкой, или же использовать FString который будет брать другой FString, так же видны несколько оверлодов операторов. Пролистав ниже мы можем найти ещё больше конструкторов которые берут разные типы данных в качестве параметров:
Если пролистать ещё дальше можно найти функции:
В целом если посмотреть на открывшийся заголовочный файл можно сделать вывод что нам в руки дали огромный арсенал относящийся к FString, поэтому было бы странно его использовать так как скорее всего нам, при использовании стандартного С++ string, пришлось бы очень быстро изобретать велосипед и думать о том как он запуститься на разных платформах.
Окей. Вернемся к форматированию. Обычно когда мы начинаем делать инструмент отладки мы, окромя каких то параметров так же хотим знать имя объекта параметры которого мы сейчас отображаем. Для этого мы воспользуемся точно такой же конструкцией как и раньше но используем наследуемую от класса Actor функцию GetName(); :
Окей. Вернемся к форматированию. Обычно когда мы начинаем делать инструмент отладки мы, окромя каких то параметров так же хотим знать имя объекта параметры которого мы сейчас отображаем. Для этого мы воспользуемся точно такой же конструкцией как и раньше но используем наследуемую от класса Actor функцию GetName(); :
В макросе TEXT() я поменял определитель формата на %s так как s стоит за string, казалось бы достаточно поменять теперь DeltaTime на Name и мы закончили, но нет. Запись будет выглядеть чуть по другому:
Казалось бы эта запись говорит о том что мы разыменовываем указатель, но это не так. * в случае с FString класс оверлодит оператор *, другими словами * имеет совершенно иной кастомный функционал отличный от стандартного. Этот функционал заключается в том что таким образом мы утилизируем C-Like запись строки, о таком типе записи мы говорили в этой теме.
Документация по FString содержит в себе полное описание всех оверлодов, с листом функций и коротким описанием что они делают. Если пролистать её достаточно в низ в ней будет секция Operators в которой расписаны все возможные варианты кастомного функционала. Первым в списке будет тот самый *:
Документация по FString содержит в себе полное описание всех оверлодов, с листом функций и коротким описанием что они делают. Если пролистать её достаточно в низ в ней будет секция Operators в которой расписаны все возможные варианты кастомного функционала. Первым в списке будет тот самый *:
Так же существует ещё одна документации которая содержит примеры того как можно использовать FString, и она так же очень и очень полезна для ознакомления. В ней есть одна очень важная строка:
Которая подтверждает факт того что мы всё сделали правильно. Вы спросите что такое TCHAR* - TCHAR
это макрос, для декларирования одного символа. Понимание того как он работает нам совершенно не важно. Но если вы любоптны вот тут можно почитать статью которая в деталях разжевывает этот и другие макросы из этой "линейки".
Для форматирования Fstring в output log, * и %s так же нужно использовать:
это макрос, для декларирования одного символа. Понимание того как он работает нам совершенно не важно. Но если вы любоптны вот тут можно почитать статью которая в деталях разжевывает этот и другие макросы из этой "линейки".
Для форматирования Fstring в output log, * и %s так же нужно использовать:
Сохраняемся. Делаем хот релод, запускаем игру и видим спам двух сообщений в OutputLog:
Обратите внимание на то что у нашего BP_Item есть "жирный" хвост. Этот хвост его уникальный ID в мире. Одинаковых объектов может быть очень и очень много, но все они отслеживаются движком и им присваивается ID. Если я сейчас возьму и на уровне скопирую свой BP_Itetm, а после запущу игру, я получу больше сообщений на экран:
Само собой мы выводим на экран два совершенно разных BP_Item, у них разный ID, так же DeltaTime выводится дважды за 1 фрейм в аутпут лог.
С форматированием разобрались. Дальше будем делать дебаг-шейпы.
С форматированием разобрались. Дальше будем делать дебаг-шейпы.
#ue5