Глава 18. Изображения <image>
В прошлых главах мы, в основном, работали с одним лишь только текстом и лишь слегка затронули иконки (<item/>), согласитесь, что этого мало. Иногда нужно прямо-таки ткнуть игроку в какое-то место на экране или вывести какое-то изображение на экран. С текстур-паками все становится еще круче, так как можно заменить оригинальный спрайт (картинку) на любой другой, что открывает колоссальные просторы для творчества
Для работы с изображениями в игре есть тег <image/>. Он позволяет выводить спрайты (картинки) прямо в диалог или сразу на экран игроку.
Шаг 1. Синтаксис и атрибуты
Принцип работы <image/> полностью аналогичен работе <label/>, имеет те же теги и тот же функционал. Разница лишь в том, что <image/> выводит спрайты (картинки), а не текст.
Одиночный:
<image atlas="GUI" sprite="Hand"/>
Со вложенными тегами (в диалоге):
<image atlas="GUI" sprite="Hand"><scale x="50" y="50"/><color name="red"/></image>
Со вложенными тегами (на экране):
<image atlas="GUI" sprite="Hand" location="HUD"><scale x="50" y="50"/><color name="red"/>
<position x="100" y="0"/>
<rotation angle="0"/><persist /></image>
Где:
Атрибуты
atlas– Атлас. Как бы альбом, в котором лежит картинкаsprite– Спрайт. Системное имя самой картинкиlocation– Где будет находится спрайт
Вложенные теги
<color/>– Цвет. Можно в форматеr="0.0"g="0.0"b="0.0"(от 0.0 до 1.0) илиname="ИмяЦвета"(см. GigaList)<scale/>– Растянуть картинку по X и Y в пикселях<rotation/>– Поворот текст в градусах. Против часовой стрелки – положительные координаты (90, 30…), По часовой – отрицательные (-90, -180…)<position/>– Внутриигровая позиция на экране. Работает только вместе с<persist/>, в диалоге ни на что не влияет<persist/>– Оставить спрайт на экране
Таблицу всех поддерживаемых текстовых имен цветов можно посмотреть в GigaList, раздел «Цвета (Текст)»
Шаг 2. Атласы и спрайты
Известные атласы и спрайты в них. В формате: Атлас (доступные спрайты):
- GUI (Hand, RadarArrowGreen, SqareEmpty, Button400x70)
- Moga (Pro)


Если указать несуществующий атлас\спрайт, то это или сломает диалог, или просто выведет пустоту, вместо картинки. Используйте только те, что указаны выше
Одиночный тег почти всегда непригоден для вывода, так как почти все картинки базово будут выглядеть очень мелко
Шаг 3. Изображения в диалоге
В диалоге <image/> ведет себя как обычный элемент, то бишь порядок вывода такой же, как в коде, картинки идут в одном потоке вместе с иконками и текстом от label. Тег position в диалоге ни на что не влияет
Давайте добаим спрайт руки, указывающий на яблоко в spider_hunt_step:
<step id="spider_hunt_step"><desc>Хорошо. Попробуй убить парочку пауков для разминки. Также принеси мне яблочко, а то я уж больно проголодался</desc><image atlas="GUI" sprite="RadarArrowGreen"><scale x="50" y="50"/></image><item name="Apple" count="1"/>. . .</step>

Как видите, стрелка немного съехала, относительно яблока. Давайте это исправим + поместим яблоко со стрелкой в центр диалогового окна
Чтобы это сделать мы будем использовать сильнорастянутый по x «<label> </label>» + row, обратите внимание на пробел внутри label.
<step id="spider_hunt_step"><desc>Хорошо. Попробуй убить парочку пауков для разминки. Также принеси мне яблочко, а то я уж больно проголодался</desc><row><label><scale x="310" y="3"/></label><image atlas="GUI" sprite="RadarArrowGreen"><scale x="50" y="50"/></image></row><row><label><scale x="300" y="3"/></label><item name="Apple" count="1"/></row>. . .</step>

Шаг 4. Спрайт на экране
Как и label, спрайт можно прилепить к экрану через location + persist. Спрайт будет висеть, пока игрок находиться на этом шаге. Как только уйдет на другой шаг – исчезнет.
Давайте к нашей надписи «Цель: 2 паука и яблоко» прилепим слева сбоку руку, которая пальцем будет указывать на нашу надпись. Для поворота спрайта используем тег c атрибутом <rotation/>angle.
<step id="spider_hunt_step"><desc>Хорошо. Попробуй убить парочку пауков для разминки. Также принеси мне яблочко, а то я уж больно проголодался</desc><row>. . .</row><row>. . .</row><!-- Стрелка слева -->
<image atlas="GUI" sprite="RadarArrowGreen" location="HUD"><scale x="50" y="50"/><position x="-235" y="-310"/><persist /><rotation angle="90"/></image>
<!-- Стрелка справа--><image atlas="GUI" sprite="RadarArrowGreen" location="HUD"><scale x="50" y="50"/><position x="180" y="-315"/><persist /><rotation angle="-90"/></image>. . .</step>

Аналогично можно сделать «подложку» для текста Цели:
<step id="spider_hunt_step"><desc>Хорошо. Попробуй убить парочку пауков для разминки. Также принеси мне яблочко, а то я уж больно проголодался</desc><row>. . .</row><row>. . .</row><!-- Стрелка слева --><image atlas="GUI" sprite="RadarArrowGreen" location="HUD"><scale x="50" y="50"/><position x="-235" y="-315"/><rotation angle="90"/><persist /></image><!-- Стрелка справа --><image atlas="GUI" sprite="RadarArrowGreen" location="HUD"><scale x="50" y="50"/><position x="190" y="-315"/><rotation angle="-90"/><persist /></image><!-- Подложка --><image atlas="GUI" sprite="Button400x70" location="HUD"><scale x="385" y="50"/><position x="-25" y="-315"/><persist /></image>. . .</step>

Задания на закрепление
- Поэкспериментируйте со
<scale/>у спрайта руки (Hand) в диалог. Растяните её по X и Y, а затем посмотрите, что получится. Аналогично можете провернуть это со всеми остальными спрайтами. Попробуйте покрасить каждый элемент в какой-либо цвет - Выведите на экран 4 кнопки (для текста
label, для фона спрайта кнопкиimage). Расставьте их вокруг прицела (0, 0) со всех четырех сторон.
Заключение
В этой Главе вы научились работать со спрайтами. Выводить их на экран или в диалогвоое окно, позиционировать их, а также растягивать и перекрашивать. Количсетво встроенных спрайтов сильно ограничено, но с текстур-паками <image/> превращается в мощный инструмент, когда вы можете подменить оригинальный спрайт на что-то своё.
Итоговый код Главы
MyQuest.xml – «Основной Квест»
<?xml version="1.0" encoding="UTF-8"?><quest npc="Wizard" title="Основной Квест1"><step id="#start"><intro>Привет, [FFAA00]как дела[-]?</intro><desc>[FFAA00]Рад[-] тебя снова видеть! Как дела?</desc><option to="bad_mood_step" text="[FF0000]Плохо[-]"/><option to="good_mood_step" text="[00FF00]Норм[-]"><journal/></option></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><row><label><scale x="310" y="3"/></label><image atlas="GUI" sprite="RadarArrowGreen"><scale x="50" y="50"/></image></row><row><label><scale x="300" y="3"/></label><item name="Apple" count="1"/></row><!-- Стрелка слева --><image atlas="GUI" sprite="RadarArrowGreen" location="HUD"><scale x="50" y="50"/><position x="-235" y="-315"/><rotation angle="90"/><color name="cyan"/><persist /></image><!-- Стрелка справа --><image atlas="GUI" sprite="RadarArrowGreen" location="HUD"><scale x="50" y="50"/><position x="190" y="-315"/><rotation angle="-90"/><persist /></image><!-- Подложка --><image atlas="GUI" sprite="Button400x70" location="HUD"><scale x="385" y="50"/><position x="-25" y="-315"/><persist /></image><option to="#close" text="Ок"/><rewards type="Award"><reward exp="300"/><row><reward item="Axe" count="5"/><reward recipe="Sunshard Paula" type="Table"/></row></rewards><label location="HUD"><persist/><position x="-200" y="-300"/><scale x="24" y="24"/>[FFAA00]Цель:[-] 2 паука и яблоко</label><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><rewards type="Display"><reward exp="300"/><row><reward item="Axe" count="5"/><reward recipe="Sunshard Paula" type="Table"/></row></rewards><option to="spider_hunt_step" text="Уйти"/><option to="go_to_warrior_step" text="Ок"><remove item="Apple" count="1"/><reward exp="300"/><reward item="Axe" count="5"/><reward recipe="Sunshard Paula" type="Table"/></option><info><label>Вернись к Волшебнику и скажи, что ты убил всех пауков</label></info></step><step id="go_to_warrior_step"><desc>На этом пока что всё. Мне нечего тебе поручить. Сходи к Аарону, может быть, у него есть что-то для тебя</desc><option to="#close" text="Ок"/><info><label>Выполни поручение от Аарона</label></info><option auto="before_find_pig_spawner_step"><complete quest="Маленькая Проблемка" step="after_aragog_step" /></option></step><step id="before_find_pig_spawner_step"><desc>Всё таки у меня есть для тебя поручение</desc><option to="find_pig_spawner_step" text="Ок"/></step><removestep id="find_pig_spawner_step"><intro>Собери-ка мне спавнер Свиньи</intro><desc>Так ты будешь собирать?</desc><finish>О, а вот и мой спавнер</finish><remove item="Antique Spawner" data="56" count="1" /><rewards><reward exp="500"/></rewards><option to="after_pig_go_warrior" text="Ок"/></removestep><step id="after_pig_go_warrior"><desc>Спасибо, Наездник Дракона, а теперь сходи опять к Аарону. У него опять есть для тебя какое-то задание</desc><option to="#close" text="Ок"/><info><label>Иди к Аарону ([FFFF00]опять[-])</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="Назад"><reward item="Health Potion" count="1000"/></option></step><step id="brew_health_potion_step"><desc>Могу предложить тебе сварить Зелье Здоровья. Это должно помочь поднять тебе настроение.</desc><option to="#close" text="Понял"/><label>Вот рецепт:</label><recipe name="Health Potion" type="Cauldron" /><label><scale x="1000" y="8"/>[FFFF00]_[-]</label><row><label>Скрафти Котел</label><item name="Cauldron" count="0"/><label>и помести:</label></row><row><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>После приготовления, подойди к Волшебнику!</label> <!-- --><label></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 auto="return_to_wizard_step"><collect item="Health Potion" count="1"/> <!-- --></option></step><step id="return_to_wizard_step"><desc>Отлично! Вижу, что ты справился</desc><option to="consume_health_potion_step" text="Ок"/><label location="HUD"><persist/><position x="-200" y="-300"/><scale x="24" y="24"/>[FFAA00]Цель:[-] Отнести зелья Волшебнику</label><info><label>Вернись к Волшебнику и скажи, что ты сварил Зелье</label></info></step><consumestep id="consume_health_potion_step"><intro>Теперь выпей это Зелье! Тебе сразу же полегчает</intro><desc>Давай пей. Чего ты ждёшь?</desc><finish>Вот видишь. Я прямо вижу, как ты стал здоровее выглядеть!</finish><consume target="Player" item="Health Potion" count="1"/><rewards><reward exp="50"/></rewards><option to="#end_dark_side" text="Ок"/></consumestep><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 только что обновил, просто изначально забыл добавить
Из нюансов: У них пока что нет своего портрета, поэтому будет видно просто имя