Этап 3. Оформление квестов
Глава 12. Визуальное оформление
В прошлых Главах мы научились писать диалоги, давать задания, вести Журнал, но это всё выглядит слишком… скучно. Обычный голый текст, обычные кнопки, скрытные, как партизаны, авто-опции, которые «что-то там делают» за глазами игрока. В общем, одно сплошное уныние
Благо, в игре есть встроенный функционал, позволяющий оживить квесты. В официальнывх квестах он активно используется. Давайте не будем отставать и тоже начнем красиво оформлять наши творения.
Шаг 1. Цветной текст
Пожалуй, самый простой способ разообразить диалоги — добавить цветной текст. Работает в любом текстовом поле: desc, intro, label, notify (его рассмотрим ниже), а также в тексте на кнопках
Как работает:
[FF0000] МойТекст [-]
Где:
[FF0000]– HEX-код цвета в форматеRRGGBB. Это сам цвет.[-]– Сброс цвета обратно на белый. Граница раскраски. Можно не ставить, если идет несколько раскрасок подряд и белый (или зеленый) текст не нужен:[BC8F8F]мл.[FF0000]Арагог
Часто используемые цвета:
1. Красный: [FF0000]
2. Зелёный: [00FF00]
3. Синий: [0000FF]
4. Жёлтый: [FFFF00]
5. Оранжевый: [FFAA00]
Всю палитру HEX-кодов можно посмотреть здесь: https://get-color.ru/all/
Интересный факт:
Вы также можете сделать цветное имя для своего питомца! Для этого в имя питомца просто добавляйте блоки цветного текста


Откроем MyQuest.xml, чтобы покрасить текст Волшебника и кнопки в #start:
<?xml version="1.0" encoding="UTF-8"?><quest npc="Wizard" title="Мой Первый Квест"><step id="#start"><intro>Привет, [FFAA00]как дела?[-]</intro><desc>[FFAA00]Рад[-] тебя снова видеть! Как дела?</desc><option to="bad_mood_step" text="[FF0000]Плохо[-]"/><option to="good_mood_step" text="[FFFF00]Норм[-]"/></step>. . .</quest>
В игре:


Шаг 2. Переносы строк
Иногда весь текст выведенный в один сплошной абзац выглядит некрасиво. Для этого можно использовать переносы
Есть 2 способа перенести строку:
- Символ
\nв тексте:<desc>Снова ты?\nМоё предложение всё ещё актуально. \nГотов приступить?</desc> - Перенос прямо в коде:
<intro>Это хорошо, что хорошо.У меня есть одно плёвое заданьеце для тебя.Готов ли его выполнить?</intro>
В игре:


Важно! Если не хотите, чтобы ваш текст съехал, то не ставьте пробелы (Tab’ы можно) после переноса строки
Правильно: Снова ты?\nМоё предложение всё ещё актуально.
Неправильно: Снова ты?\n Моё предложение всё ещё актуально. (пробел после \n сдвинет строку)
Давайте применим оба способа сразу в рамках нашего квеста. Изменим good_mood_step
<step id="good_mood_step"><intro>Это хорошо, что хорошо.У меня есть одно плёвое заданьеце для тебя.Готов ли его выполнить?</intro><desc>Снова ты?\nМоё предложение всё ещё актуально.\nГотов приступить?</desc><option to="spider_hunt_step"text="Да"><journal/></option><option to="#start" text="Назад"/></step>
Ещё раз напомню: Табы ставить можно, игра их не видит и не добавляет
Шаг 3. Уведомления <notify/>
Тег <notify> показывает всплывающее уведомление вверху экрана. Отлично подходит для сообщений типа: «Задание выполнено!» «Вы погибли!» и так далее
Важно! <notify> используется только внутри опций (авто или кнопки). В <info> не работает
Давайте добавим уведомление: «Задание выполнено! Вернись к Волшебнику!» в spider_hunt_step и отформатируем его:
<step id="spider_hunt_step"><desc>Хорошо. Попробуй убить парочку пауков для разминки. Также принеси мне яблочко, а то я уж больно проголодался</desc><option to="#close" text="Ок"/><info><kill enemy="Spider" count="2"/><collect item="Apple" count="1"/></info><option auto="after_hunt_step"><kill enemy="Spider" count="2"/><collect item="Apple" count="1"/><notify>[00FF00]Задание выполнено![-] \nВернись к Волшебнику!</notify></option></step>
В игре (верхняя часть экрана):
Несколько уведомлений выводятся по-очереди друг за дружкой:
Шаг 4. Иконки предметов <item/>
Можно вставить иконку предмета прямо в текст диалога и Журнала. Добавляет наглядности, когда игрок сразу видит, что ему надо принести
Добавим иконки в диалог
Иконки в диалоге размещаются прямо внутри <step> на уровне <desc> и <intro>:
<step id="spider_hunt_step"><desc>Хорошо. Попробуй убить парочку пауков для разминки. Также принеси мне яблочко, а то я уж больно проголодался</desc><item name="Apple" count="1"/><option to="#close" text="Ок"/>. . .</step>
В игре:
Также можно несколько предметов сразу:
<step id="spider_hunt_step"><desc>Хорошо. Попробуй убить парочку пауков для разминки. Также принеси мне яблочко, а то я уж больно проголодался</desc><item name="Apple" count="1"/>
<item name="Apple" count="2"/>
<item name="Apple" count="3"/>
<item name="Apple" count="4"/><option to="#close" text="Ок"/>. . .</step>
Аналогично можно добавить иконки в info:
<step id="spider_hunt_step">. . .
<info><kill enemy="Spider" count="2"/><collect item="Apple" count="1"/><item name="Apple" count="1"/><item name="Apple" count="2"/><item name="Apple" count="3"/><item name="Apple" count="4"/></info>. . .</step>
Шаг 5. Чистые иконки
Если поставить count="0", то можно получить только иконку предмета без пометки “x [количество]“:


Если count не указан или 1 и больше, то рядом с иконкой будет приписка: “x [количество]“
Отрицательные числа в count работают аналогично count="0", но использовать отрицательные числа крайне не рекомендуется из-за риска ошибок
В итоговом варианте оставляем по одному яблоку в info и диалоге:
<step id="spider_hunt_step"><desc>Хорошо. Попробуй убить парочку пауков для разминки. Также принеси мне яблочко, а то я уж больно проголодался</desc><item name="Apple" count="1"/><option to="#close" text="Ок"/><info><kill enemy="Spider" count="2"/><collect item="Apple" count="1"/>
<label>Яблоко: </label><item name="Apple" count="1"/></info><option auto="after_hunt_step"><kill enemy="Spider" count="2"/><collect item="Apple" count="1"/><notify>[00FF00]Задание выполнено![-] \nВернись к Волшебнику!</notify></option></step>
Шаг 6. Рецепты <recipe/>
Принцип работы тега <recipe/> схож с <item/>.
<item name="Apple" count="1"/><recipe name="Axe" type="Table"/>
Всего существует 4 типа верстака:
- Player – 2×2 поле крафта в инвентаре игрока
- Table – Верстак
- Furnace – Печка
- Cauldron – Котёл
Тип верстака очень важен!
Работает в Журнале (внутри <info>) и Диалоговом окне (внутри <step>).
В name указывается только Системное имя. Все Системные имена Рецептов, отсортированные по Типу верстака можно найти в таблице GigaList.xlsx, которую можно скачать в начале Гайда

Давайте теперь поменяем Блок Плохого Настроения.
Сейчас всё работает так: #start –> Кнопка «Плохо» –> #end_dark_side
Слишком просто и примитивно. Давайте сделаем так, что если игрок идет в ветку Плохого настроения, то Волшебник предложит ему сварить несколько зелий исцеления.
1) Создадим свой собственный шаг brew_health_potion_step:
В данном случае использовать intro смысла немного, поэтому оставим только desc.
<!-- Плохое настроение --><step id="bad_mood_step">
. . .
</step><step id="brew_health_potion_step"><desc>Могу предложить тебе сварить Зелье Здоровья. Это должнго помочь поднять тебе настроение.\nВот рецепт:</desc><recipe name="Health Potion" type="Cauldron" />
<info><label>Свари Зелье Здоровья по рецепту: </label><recipe name="Health Potion" type="Cauldron" /><label>Относить Волшебнику его [FF0000]не нужно[-]</label></info><option to="#close" text="Понял"/></step><step id="#end_dark_side">
. . .
</step>
2) Теперь доработаем bad_mood_step, исправим текст и то, куда ведет кнопка «:(»
Было:
<!-- Плохое настроение --><step id="bad_mood_step" ><intro>Очень жаль! Крепись там. Удачи, Наездник Дракона!</intro><desc>Понимаю, что тебе сейчас не хорошо, но у меня сейчас нет времени на разговоры</desc><option to="#end_dark_side" text=":("/><option to="#start" text="Назад"/></step>
Стало:
<!-- Плохое настроение --><step id="bad_mood_step" ><intro>Очень жаль! Крепись там</intro><desc>Понимаю, что тебе сейчас не хорошо, крепись там!</desc><option to="brew_health_potion_step" text=":(">
<journal/>
</option><option to="#start" text="Назад"/></step>
Главное про <journal/> не забудьте без него в Журнале не появиться отметка
3) Проверяем:
Шаг 7. Группировка
По умолчанию игра выводит каждую иконку и каждый рецепт с новой строки. В результате может получится монструозный столб, который способен аж пол-экрана закрывать. К счастью, в игре есть механизмы группировки в одну строку (либо несколько строк). Для этого используется тег <row>. Этот тег можно использовать только в Диалогах, в Журнале (info) он ломает вывод иконок/рецептов
Без группировки:
<desc>Без группировки:</desc><item name="Health Potion" count="1"/><item name="Mana Potion" count="1"/>

В одну строку:
<desc>В одну строку:</desc>
<row><item name="Health Potion" count="1"/><item name="Mana Potion" count="1"/></row>

В несколько строк:
<desc>В несколько строк:</desc>
<row><item name="Health Potion" count="10"/><item name="Health Potion" count="20"/></row><row><item name="Mana Potion" count="30"/><item name="Mana Potion" count="11"/></row>

Как видите, row пишется на том же уровне, что и desc/intro, и уже внутрь него помещаются иконки, рецепты и т.д.
Можно даже в комбинации:

<desc>В комбинации с рецептами:</desc><row><recipe name="Health Potion" type="Cauldron" /><item name="Health Potion" count="10"/><item name="Health Potion" count="20"/></row><row><item name="Mana Potion" count="30"/><item name="Mana Potion" count="11"/><recipe name="Mana Potion" type="Cauldron" /></row>
Напомню, что <row> можно использовать только в Диалогах, в Журнале (info) он ломает вывод иконок/рецептов
Опробуем его на примере шага brew_health_potion_step:
Было:
<step id="brew_health_potion_step"><desc>Могу предложить тебе сварить Зелье Здоровья. Это должно помочь поднять тебе настроение.\nВот рецепт:</desc><recipe name="Health Potion" type="Cauldron" /><info><label>Свари Зелье Здоровья по рецепту: </label><recipe name="Health Potion" type="Cauldron" /><label>Относить Волшебнику его [FF0000]не нужно[-]</label></info><option to="#close" text="Понял"/></step>
Стало:
<step id="brew_health_potion_step"><desc>Могу предложить тебе сварить Зелье Здоровья. Это должно помочь поднять тебе настроение.\nВот рецепт:</desc><recipe name="Health Potion" type="Cauldron" /><row><item name="Cauldron" count="1"/><item name="Lilia Flower" count="1"/><item name="water" count="1"/><item name="Energy" count="1"/></row><info><label>Свари Зелье Здоровья по рецепту: </label><recipe name="Health Potion" type="Cauldron" /><label>Относить Волшебнику его [FF0000]не нужно[-]</label><label>Для приготовления потребуются: </label><item name="Cauldron" count="1"/><item name="Lilia Flower" count="1"/><item name="water" count="1"/><item name="Energy" count="1"/></info><option to="#close" text="Понял"/></step>
В игре:

Задания на закрепление
- Раскрасьте ещё какой-нибудь текст или кнопки в квесте
- Сделайте квест от Теда (
Viking), в котором он просит принести ему 3 кости и 5 яблок, которые он заберет у игрока. В Журнал добавьте Цели (потребуетсяcollect+remove) и иконки самих предметов с их количеством. - Сделайте квест от Алхимика (
ShadowHunter), в котором он показывает рецепт Зелья Здоровья И рецепт Зелья Маны в одну строку. Когда игрок возьмет эти зелья, сверху должно всплыть уведомление: «Все зелья собраны, отнеси их Алхимику», а текст и цели в Журнале сменятся на: «Отнеси собранные зелья Алхимику»
Заключение
В этой Главе мы научились делать текст красивым и разнообразным: красить в любые цвета, изменять цвет имени питомцам, выводить уведомления, переносить строки двумя разными способами, вставлять иконки и рецепты в Журнал и Диалоги, группировать всё это в одну строку
Теперь ваши квесты не будут выглядеть, как унылый и однообразный текст, а как полноценные и разнообразные диалоги с визуаьными подсказками. Игрок сразу видит, что от него требуют и как скрафтить тот или иной предмет.
В следующей главе мы рассмотрим расширенную работу с label, с помощью которого вы сможете вывести свои и без того красивые диалоги на Новый уровень.
Итоговый код Главы
<?xml version="1.0" encoding="UTF-8"?><quest npc="Wizard" title="Мой Первый Квест "><step id="#start"><intro>Привет, [FFAA00]как дела[-]?</intro><desc>[FFAA00]Рад[-] тебя снова видеть! Как дела?</desc><option to="bad_mood_step" text="[FF0000]Плохо[-]"/><option to="good_mood_step" text="[00FF00]Норм[-]"/></step><!-- Хорошее настроение --><step id="good_mood_step"><intro>Это хорошо, что хорошо.У меня есть одно плёвое заданьеце для тебя.Готов ли его выполнить?</intro><desc>Снова ты?\nМоё предложение всё ещё актуально.\nГотов приступить?</desc><option to="spider_hunt_step"text="Да"><journal/></option><option to="#start" text="Назад"/></step><step id="spider_hunt_step"><desc>Хорошо. Попробуй убить парочку пауков для разминки. Также принеси мне яблочко, а то я уж больно проголодался</desc><item name="Apple" count="1"/><option to="#close" text="Ок"/><info><kill enemy="Spider" count="2"/><collect item="Apple" count="1"/><label>Яблоко: </label><item name="Apple" count="1"/></info><option auto="after_hunt_step"><kill enemy="Spider" count="2"/><collect item="Apple" count="1"/><notify>[00FF00]Задание выполнено![-] \nВернись к Волшебнику!</notify></option></step><step id="after_hunt_step"><desc>Отлично! Ты справился</desc><option to="spider_hunt_step" text="Уйти"/><option to="#end" text="Ок"><remove item="Apple" count="1"/></option><info><label>Вернись к Волшебнику и скажи, что ты убил всех пауков</label></info></step><step id="#end"><desc>Прощай, Наездник Дракона! Рад был повидаться</desc><option to="#start" text="Назад"/><option to="#close" text="Пока"/></step><!-- Плохое настроение --><step id="bad_mood_step" ><intro>Очень жаль! Крепись там</intro><desc>Понимаю, что тебе сейчас не хорошо, крепись там!</desc><option to="brew_health_potion_step" text=":("><journal/></option><option to="#start" text="Назад"/></step><step id="brew_health_potion_step"><desc>Могу предложить тебе сварить Зелье Здоровья. Это должно помочь поднять тебе настроение.\nВот рецепт:</desc><recipe name="Health Potion" type="Cauldron" /><row><item name="Cauldron" count="1"/><item name="Lilia Flower" count="1"/><item name="water" count="1"/><item name="Energy" count="1"/></row><info><label>Свари Зелье Здоровья по рецепту: </label><recipe name="Health Potion" type="Cauldron" /><label>Относить Волшебнику его [FF0000]не нужно[-]</label><label>Для приготовления потребуются: </label><item name="Cauldron" count="1"/><item name="Lilia Flower" count="1"/><item name="water" count="1"/><item name="Energy" count="1"/></info><option to="#close" text="Понял"/></step><step id="#end_dark_side"><desc>Я... я тебя понимаю, Наездник Дракона. Крепись, я верю в тебя, а теперь прощай!</desc><option to="#start" text="Назад"/><option to="#close" text=". . ."/></step></quest>
Отличный гайд, но осталось несколько вопросов:
1) Куда делся раздел с кастомным магазином из прошлой версии руководства. В 13.5.0? Его больше нельзя кастомизировать?
2) У Фуза в 13.5.0 есть свой магазин, следовательно, они тоже стали квестовыми НПС и для них можно делать кастомные квесты. Или нельзя?
1) Кастомные магазины полностью убраны (даже для Алхимика, Фуза и Крестьян). Теперь игра не будет подгружать квесты, содержащие в коде тег <store>
В логах будет писать:
Skipped custom quest ‘ИмяКвеста’ from file [Путь до XML-файла квеста]: NPC stores are not allowed in custom quests
UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:LogWarning(Object)
QuestManager:AddUserQuests(XmlSerializer, String)
d__77:MoveNext()
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
2) Да, для Фуза можно теперь тоже делать квесты. Список Квестовых NPC только что обновил, просто изначально забыл добавить
Из нюансов: У них пока что нет своего портрета, поэтому будет видно просто имя