StarCraft 2: Изменение интерфейса SC2Layout

» Раздел: 1. Основы
» Автор оригинала: Helral
» Источник: http://www.sc2mapster.com/

Изначально статья планировалась как перевод статьи SC2Layout Files: Override method но, познакомившись с материалом ближе, я полностью переписал эту статью в реалиях беты 1.5.0, не оставив почти ничего от статьи автора.
Фрейм - двухмерный прямоугольный элемент интерфейса, наблюдаемый нами в игре. Может быть как простым (кнопка, подпись или изображение), так и сложным, содержащим в себе другие простые и сложные фреймы (панель команд, панель миникарты, игровое меню).

Вступление

Часто ставится задача изменить стандартный интерфейс игры, усложнив или напротив, упростив его, сменить его художественный стиль на нечто более соответствующее тематике мода, ну или просто выделиться из общей массы, добавив с свою карту неповторимый интерфейс.
В отличие от Warcraft’а III, игровой интерфейс Starcraft’a 2 не жестко зашит в код игры, а строится динамически из xml файлов, в которых хранится описание всех элементов интерфейса, и которые можно изменять по своему усмотрению.
Как это работает? При построении интерфейса в игре сначала берутся SC2Layout-шаблоны, находящиеся в архивах игры, затем к ним применяются изменения, привносимые более поздней версией игры, а уж затем применяются пользовательские SC2Layout файлы.
Важно! Все стандартные значения и настройки элементов интерфейса остаются в силе, до тех пор, пока мы их не изменим в своем SC2Layout файле.
Для всех манипуляций с SC2Layout файлами служит новый модуль, добавленный в версии 1.5.0 - менеджер пользовательского интерфейса.
Все стандартные фреймы, имеющие отношение к UI игрового интерфейса, находятся прямо в окне модуля редактора интерфейса, и доступны только для чтения. Нам остается лишь там же создать новый SC2Layout, скопировать в него код нужного фрейма и изменить его в нужных местах.
В одной карте может быть сколько угодно SC2Layout файлов.
Важно. Один и тот же элемент интерфейса не может изменяться в нескольких нестандартных SC2Layout файлах. Скорей всего, при попытке изменить его в нескольких местах, фрейм станет невидимым в игре.

Создание фрейма

Чтобы изменить любой стандартный фрейм, его нужно скопировать его описание в свой SC2Layout файл, указать его полное имя или путь к его шаблону, и отредактировать старые или добавить новые теги и параметры.
Пустой файл «.SC2Layout» выглядит так:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Desc>
…
</Desc>
Важно. При создании нового фрейма, редактор UI делает несколько ошибок в его описании. Правильный код должен быть таким, как приведенный выше.
Первое что нам нужно сделать - создать тег Frame, который будет содержать тип нашего фрейма, его имя, возможно путь к его шаблону, и файл, где он описан. Он имеет такой вид
<Frame type="Image" name="CommandPanelFrame">
<Frame type='CommandPanel' name='GameUI/UIContainer/ConsoleUIContainer/CommandPanel' file='GameUI'>
Тег Frame имеет следующие параметры
  • тип (type) фрейма - для простых фреймов (кнопка, изобращение) определяет их сущность, возможные параметры и качества. Для сложных составных фреймов - является идентификатором.
  • Имя (name) фрейма - для простых просто текстовая метка, нужная для их идентификации. А для составных - содержит полный путь к этому фрейму через всю иерархию интерфейса.
  • Шаблон (template) - необходима для составных фреймов. Содержит путь к шаблону, в котором это фрейм описан. Может быть найден в файле GameUI.SC2Layout.
  • Файл(file) - имя файла игрового интерфейса, в котором описан этот фрейм. Обычно это "GameUI".
Важно! Простейший способ получить правильную иерархию для сложного фрейма – воспользоваться структурированным обзором, содержащим все доступные фреймы, написанным Helral’ом. Сперва нужно найти в нем нужный фрейм, нажать «Show Frame Notation» и скопировать его полное имя. Все символы ' необходимо заменить на ".

Привязка и расположение фрейма

Это самая-самая важная операция при работе с фреймами.
Без четкого понимания принципов ее работы, осознанно изменять интерфейс игры не выйдет.
Она кажется запутанной, но после практики, пользоваться ею станет несложно.
При помощи тега Anchor , фреймы размещаются относительно друг с друга, на расстоянии, определяемом метками и отступами в пикселах, независимо от разрешения экрана.
<Anchor side=”Top” relative=”$parent” pos=”Min” offset=”0”/>
Рассмотрим подробно все его атрибуты:
  • side Left/Right/Top/Bottom – сторона фрейма которую мы привязываем
  • relative – ссылка на другой фрейм, относительно которого сторона будет расположена
    • $this – ссылка на себя ( то есть, фрейм ни к кому не привязан, откреплен)
    • $parent – ссылка на предыдущий по иерархии фрейм.
    • $parent/name – ссылка на фрейм name, который описан в предыдущем фрейме
  • pos Min/Mid/Max – метка, обозначающая край relative фрейма, к которому будет привязана side нашего фрейма. Min находится с левой и верхней сторон relative фрейма, Max – с правой и нижней стороны, а Mid – по его центру.
  • offset – отступ от pos на заданное число пикселей в сторону, определяемую знаком. Положительные значения сдвинут текущую сторону к Max, а отрицательные – к Min relative фрейма.
Тег Anchor можно прочитать так: берем сторону side нашего фрейма, перемещаем ее к краю pos фрейма relative с отступом в offset пикселей.
Чтобы прикрепить один фрейм к другому достаточно двух якорей для двух сторон – один по горизонтали и один по вертикали.
Два якоря с каждой стороны (напр. Left и Right), используются для того чтобы расположить фрейм точно посередине relative фрейма или чтобы привязать разные края к нескольким различным фреймам.
!!Важно! При работе с якорями нужно помнить, что все параметры, указанные в стандартных файлах игры продолжают действовать, пока мы их не изменим!!!
Переопределяя стороны (side) стандартных фреймов, нужно или работать лишь с теми сторонами, которые упомянуты в стандартных файлах, или указывать параметры для всех четырех сторон фрейма.

Еще немного теории

Рассмотрим следующее изображение.
На нем несколько фреймов закреплены к разным краям черного фрейма, под которым подразумевается окно игры.
Теперь попробуем представить, каким образом каждый из этих фреймов прикреплен к relative фрейму.
Для наглядности будем считать, что все фреймы привязаны к предыдущему по иерархии фрейму (relative=”$parent”).
1. Фрейм А. Привязан двумя сторонами - левой и нижней. Теги для этих сторон будут выглядеть так:
<Anchor side=”Left” relative=”$parent” pos=”Min” offset=”0” />
<Anchor side=”Bottom” relative=”$parent” pos=”Max” offset=”0”/>
2.Фрейм B.Левой стороной привязан к середине, а нижней - к низу окна игры. При чем, он частично выступает за край окна.
<Anchor side=”Left” relative=”$parent” pos=”Mid” offset=”0” />
<Anchor side=”Bottom” relative=”$parent” pos=”Max” offset=”150”/>
3. Фрейм С. Он находится ровно по центру окна игры. Реализуется это при помощи 4 тегов Anchor, которые можно привязать или к краям, или к середине relative фрейма:
<Anchor side=”Left” relative=”$parent” pos=”Min” offset=”0” />
<Anchor side=”Bottom” relative=”$parent” pos=”Max” offset=”0”/>
<Anchor side=”Right” relative=”$parent” pos=”Max” offset=”0” />
<Anchor side=”Top” relative=”$parent” pos=”Min” offset=”0”/>
4. Фрейм D. Ошибочно помещен за краем окна игры - то есть, он невидим.
<Anchor side="Left" relative="$parent" pos="Max" offset="0"/>
<Anchor side="Top" relative="$parent" pos="Min" offset="0"/>
Совет. Поместить один фрейм посредине другого можно еще двумя другими способами.
  1. Привязав все 4 стороны к Mid relative фрейма:
<Anchor side=”Left” relative=”$parent” pos=”Mid” offset=”0” />
<Anchor side=”Bottom” relative=”$parent” pos=”Mid” offset=”0”/>
<Anchor side=”Right” relative=”$parent” pos=”Mid” offset=”0” />
<Anchor side=”Top” relative=”$parent” pos=”Mid” offset=”0”/>
  1. Если фрейм создан нами и не упоминается ранее, то можно это сделать еще изящней:
<Anchor relative=”$parent”/>

Практика

Теперь сделаем несколько несложных, но заметных изменений интерфейса.

Перемещение панели миникарты

Переместим миникарту из левого нижнего угла в правый нижний, и расположим кнопки управления ею вверху, непосредственно над ней самой.
  1. Создаем новый SC2Layout файл.
  1. Добавляем в него новый фрейм типа MinimapPanel. Имя берем из страницы с иерархией фреймов. Шаблон фрейма упоминается в файле его описания (MinimapPanel.SC2Layout).
Таким образом, тег фрейма будет иметь следующий вид:
<Frame type="MinimapPanel" name="GameUI/UIContainer/ConsoleUIContainer/MinimapPanel" template="MinimapPanel/MinimapPanelTemplate" file="GameUI">
  1. Копируем из файла MinimapPanel.SC2Layout описание фрейма, которое выглядит так:
<Frame type="MinimapPanel" name="MinimapPanel" template="MinimapPanel/MinimapPanelTemplate">
    <Anchor side="Left" relative="$parent" pos="Min" offset="0"/>
    <Anchor side="Bottom" relative="$parent" pos="Max" offset="0"/>
    <Width val="395"/>
    <Height val="327"/>
</Frame>
По этому описанию можно выяснить то, что панель миникарты привязана к окну игры левой и нижней стороной. Чтобы прикрепить ее к правой стороне экрана недостаточно просто заменить side="Left" на side="Right", как кажется на первый взгляд. Если так сделать, то миникарта окажется посередине экрана, так как тег для левой стороны продолжит действовать.
  1. Необходимо сперва отвязать левую сторону нашего фрейма от окна игры, указав relative="$this", а затем добавить тег Anchor для правой стороны фрейма.
    <Anchor side="Right" relative="$parent" pos="Max" offset="0"/>

Перенесем кнопки управления миникартой

Первое, что для этого нужно сделать - это изменить размер фрейма миникарты (чтобы убрать область справа для кнопок, и добавить для них больше места по вертикали), а саму миникарту привязать немного ниже, что сверху ее фрейма было свободное место для кнопок.
!!Важно! Если расположить фрейм за пределами relative фрейма, он станет невидимым в игре!!!
  1. Устанавливаем новый размер для панели миникарты. Для этого нужно задать новые значения для ширины и высоты при помощи соответствующих тегов:
<Width val="300"/>            
<Height val="375"/> 
  1. Теперь нужно опустить саму миникарту ниже, от верхнего края ее фрейма. Для этого нужно добавить в тело фрейма MinimapPanel описание фрейма Minimap.
Оставим только описание его якорей, все остальное удалим (все это описано в стандартном файле и итак будет в игре).
И увеличим offset для верхней стороны фрейма до 60 пикселей.
<Anchor side="Top" relative="$parent" pos="Min" offset="60"/>
  1. Размещаем кнопку пинга в центре над миникартой. Копируем описание фрейма PingButton из файла MinimapPanel.SC2Layout.
В поле name указываем полное имя, добытое из иерархии фреймов(www.helral.eu/SC2LayoutFrames.html).
<Frame type="Button" name="GameUI/UIContainer/ConsoleUIContainer/MinimapPanel/PingButton" template="MinimapPanel/MinimapButtonTemplate" file="GameUI">
Для правой стороны устанавливаем offset 0
Добавляем Anchor для левой стороны с pos="Min".
Теперь по горизонтали кнопка будет находиться по центру фрейма панели миникарты.
Отвязываем нижнюю сторону фрейма relative="$this"
И добавляем тег Anchor для верхней стороны фрейма.
<Anchor side="Top" relative="$parent" pos="Min" offset="-0"/>
Совет. Теги фрейма, которые не нужно изменять, можно удалить из нестандартного SC2Layout файла. Они имеются в стандартном файле, и изменения, вносимые им в любом случае, войдут в игру.
  1. Размещение кнопки террайн справа от кнопки пинга.
Операции аналогичны выше – копируем описание из MinimapPanel, находим полное имя в иерархии фреймов, и точно так же привязываем якоря.
Единственное различие – для левой стороны кнопки устанавливаем оffset=96 (двукратное значение ширины кнопки)
<Anchor side="Left" relative="$parent" pos="Min" offset="96"/>
  1. Кнопку союза размещаем слева от пинга
Все то же самое, но для правой стороны задаем offset=-96

Изменяем панель команд

Первое что нужно сделать, изменяя панель команд (хотя это верно и для всех прочих фреймов) - наглядно начертить на бумаге или в графическом редакторе, как этот фрейм должен выглядеть.
Необходимо продумать размеры кнопок, расстояние между ними и каким образом они будут друг к другу крепиться.
Для примера я подготовил эту нехитрую схему, на основе которой и сделаю новую панель.
Моя панель команд будет находиться внизу, посередине экрана. Размер кнопок будет разным: 80х80, 64x64, 64х128 и 80х64.
Немного о стандартной панели команд
  • Стандартная панель команд имеет 15 кнопок.
  • Их нумерация начинается с 00 и оканчивается номером 14.
  • Размер кнопок равен 80 пикселов.
  • offset между кнопками задает константа CommandButtonGap, равная 1 пикселю.
  • Кнопка 00 крепится к левому верхнему углу фрейма CommandPanel, а все остальные кнопки – к кнопкам, находящимся слева и вверху.
Для начала подготовим фрейм CommandPanel
  1. Копируем описание фрейма CommandPanel в свой файл. Находим и подставляем полное имя, чтобы первая строка фрейма имела вид:
<Frame type="CommandPanel" name="GameUI/UIContainer/ConsoleUIContainer/CommandPanel" file="GameUI">
  1. Изменяем расположение панели команд относительно экрана. Для этого нужно добавить тег Anchor для левой стороны, чтобы весь фрейм оказался в середине экрана.
<Anchor side="Left" relative="$parent" pos="Min" offset="0"/>   
  1. Рассчитаем необходимые размеры фрейма с учетом новых размеров кнопок и установим эти значения.
Высота: 80+1+128+1+80 = 290
Ширина: 80+1+80+64+ 1 +80 +1+80 = 388
<Width val="308"/> <Height val="290"/>
А теперь займемся размещением кнопок
Для экономии места и чтобы сохранить прозрачность текста, я не будут приводить подробные значения тегов для каждой кнопки, а использую сокращенную запись для фиксирования всех изменений.
Фраза «левый отвязан» значит, что для side=="Left" в качестве relative фрейма используется указатель на самого себя ”$this”, таким образом эта сторона свободна.
Выражение «верхний – в мин 05» обозначает, что side=”Top”,pos=”Max”, а relative=”$parent/CommandButton05”
Кнопка 00. Расположим ее по центру фрейма, добавив Anchor'ы для оставшихся двух сторон. Изменим ее размер на 64х128 при помощи тегов
<Width val="64"/> <Height val="128"/>
Первые 4 кнопки привязываются лишь к кнопке 00.
Кнопка 01. Левый – к мин 00, правый – к макс 00. Верхний отвязан. Нижний – к мин 00.
Кнопка 02. Верхний – к мин 00, нижний – к макс 00. Левый – к макс 00.
Кнопка 03. Верхний – к макс 00, левый – мин 00, правый – макс 00
Кнопка 04. Левый отвязан. Правый – к мин 00, верхний – мин 00, нижний – макс 00.
Теперь каждая кнопка будет привязываться сразу к двум другим. Кнопки 06 и 09 привязаны лишь к одной кнопке и имеют размеры 80х64.
Кнопка 05. Левый - к макс 01. Верхний отвязан. Нижний - к мин 02
Кнопка 06. Размер кнопки 80х64. Нижний - к макс 02. А левый -к макс 02.
Кнопка 07. Верхний - к макс 02, а левый – к макс 03.
Кнопка 08. Верхний - макс 04, а правый – к мин 03. Левый отвязан.
Кнопка 09. Меняем размер на 80х64. Левый отвязан. Нижний -макс 04. Правый - мин 04.
Кнопка 10. Верхний и левый отвязаны. Правый– к мин 01, нижний– к мин 04.
Следующие кнопки имеют размер 64х64 и привязаны сразу к двум кнопкам.
Кнопка 11. Левый – к макс 05, верхний – отвязан, нижний – к мин 06.
Кнопка 12. Левый – к макс 07, верхний – к макс 06
Кнопка 13. Верхний – к макс 09, левый отвязан, правый – к мин 08.
Кнопка 14. Левый и верхний отвязаны. Правый – к мин 10, нижний – к мин 09

Наложение изображения на фрейм

Самый, пожалуй, востребованный и часто используемый фрейм – это изображение. Этот фрейм всегда имеет тип Image и выступает в качестве фонового изображения, карты нормалей или иконки.
Рассмотрим типичные теги фрейма Image
        <Frame type="Image" name="CommandPanelFrame">
            <Anchor side="Top" relative="$parent" pos="Min" offset="0"/>
            <Anchor side="Bottom" relative="$parent" pos="Max" offset="0"/>
            <Anchor side="Left" relative="$parent" pos="Min" offset="0"/>
            <Anchor side="Right" relative="$parent" pos="Max" offset="0"/>
            <Width val="400"/>
            <Height val="275"/>
            <Texture val="@@UI/TimerWindowBackground"/>
            <TextureType val="Border"/>
            <Tiled val="true"/>
            <RenderPriority val="100"/>
        </Frame>
  • name - текстовая метка для фрейма. Нужна для идентификации фрейма.
  • с Anchor’ом мы знакомы – тут изображение размещено в центре relative фрейма.
  • Width и Height – задают размеры изображения. Если они больше, чем у relative фрейма, то часть изображения, вышедшая за эту границу, будет обрезана.
  • Texture val = путь к графическому файлу. Может быть как прямым путем к текстуре, так и ссылкой на изображение, специфичное для каждой расы.
  • Texture type = – задает тип текстуры. Возможные следующие значения: Normal, Border, Nineslice, EndCap.
В качестве примера, поместим изображение в качестве фона для панели команд
  1. Создадим в теле фрейма CommandPanel фрейм типа Image
        <Frame type="Image" name="CommandPanelFrame">
  1. При помощи 4 тегов Anchor привяжем изображение к центру фрейма панели команд.
            <Anchor side="Top" relative="$parent" pos="Min" offset="0"/>
            <Anchor side="Bottom" relative="$parent" pos="Max" offset="0"/>
            <Anchor side="Left" relative="$parent" pos="Min" offset="0"/>
            <Anchor side="Right" relative="$parent" pos="Max" offset="0"/>
++Совет. Можно было все четыре стороны просто привязать к Mid parrent фрейма.
  1. Задаем высоту и ширину изображения
            <Width val="400"/>
            <Height val="275"/>
  1. В качестве текстуры фонового изображения используем рамку для таймера, которая будет различна для каждой расы
            <Texture val="@@UI/TimerWindowBackground"/>
            <TextureType val="Border"/>
Совет. Глянуть на все доступные ссылки для элементов интерфейса для каждой расы можно в файле *"GameData\Assets.txt"*, который находится в архиве *Base.SC2Data* в папке *Liberty.SC2Mod*. Еще, его можно изменить и импортировать в свою карту, но это уже другая история.
  1. Устанавливаем приоритет рендеринга менее 500, чтобы фоновое изображение не перекрывало панель команд
            <RenderPriority val="200"/>

Другие полезные теги

Кроме возможности переместить любой фрейм или элемент интерфейса, мы можем проделать с ними множество интересных вещей, на некоторых из которых я задержусь.
Добавить комментарий в SC2Layout файл можно при помощи тега
<!-- Your comment text -->
К сожалению, комментарий можно написать лишь на английском языке, так как редактор не дает возможности писать комментарии по-русски.
Можно объявить константу, например для размеров фрейма, отступов между ними и цветов, добавив следующий тег в тело фрейма:
<Constant name="MyConstantColor" val="255,0,0"/>
А потом, просто обратиться к ней, вместо того, чтобы каждый раз использовать конкретные значения val="##MyConstantColor".
Изменить размеры фрейма можно, задав его высоту и ширину посредством тегов.
<Width val="300"/>
<Height val="100"/>
Если их не указывать в своем SC2Layout файле, то размеры, как и любые другие параметры, будут браться из стандартных файлов.
Порядок вывода фреймов. За него отвечает тег RenderPriority – который равен некому положительному числу. По умолчанию он равняется 500. Фрейм с большим приоритетом рендеринга рисуется выше фрейма с меньшим приоритетом.
<RenderPriority val="800"/>
Закрасить изображение в один цвет можно сделать при помощи пары тегов
<Desaturated val="true"/>
<DesaturationColor val="ffffff"/> 
Первый тег обесцветит изображение, а второй зальет его белым цветом. В качестве значения цвета обычно используется не RBG значение, а ссылка на объявленную ранее константу.
Поворот изображения реализуется тегом
<Rotation val="90"/>
Замощение изображением фрейма включить, или напротив, выключить при помощи тега
<Tiled val="true" layer="0"/>
Прозрачность фрейма задается значением следующего тега, и может принимать значения от 0 (прозрачно) до 255 (непрозрачно)
<Alpha val="127"/>
Скрыть фрейм или его элемент, можно добавив в его тело следующий тег
<Visible val=’False’/>
По умолчанию все фреймы видимы.

Решение проблем со SC2Layout файлами

На фрейм не действую изменения в нестандартном файле
  1. SC2Layout файл не добавлен в "Данные игрового интерфейса" (Game UI Data).
  2. Указано неверное имя для составного фрейма.
Фрейм после ваших очередных изменений стал невидимым
  1. Не указан, или указан неверно *file.*
  2. Одна и та же сторона фрейма изменяется несколько раз.
  3. Фрейм выходит за границы relative фрейма. (Напр. если левый якорь привязать к Мах, особенно с положительным оффсетом)

Скачать

Иерархия всех доступных фреймов (При копировании нужно все символы ' заменить на " )
Скачать карту с приведенными примерами (требуется версия 1.5.0)
Скачать отдельно SC2Layout файлы

Просмотров: 8 108

3 комментария удалено
ScorpioT1000 #4 - 7 лет назад -2
Теперь неактуально.
H #5 - 7 лет назад 0
ScorpioT1000:
Теперь неактуально.
с чего бы? еще как актуально. Пока близы не запилят wyswyg редактор интерфейса с экспортом в шэмээль, будет вполне даже актуально )
ScorpioT1000 #6 - 7 лет назад 0
А, перечитал, они просто сделают блокнот чтоли?
Ну, надо свой эдитор пилить тогда
Харгард #7 - 7 лет назад 0
Как-то так:
ScorpioT1000, не то, чтобы совсем блокнот, но лазить в mpq по прежнему приходится.
Хоть об импорте забыть можно. Уже легче.
H #8 - 7 лет назад 0
Да блокнот с подсветкой синтекса, который компилируется сразу в архив карты )
Кстати есть у него суперфича, можно не выходя из игры делать там изменения и сразу обновлять интерфейс. Для этого есть хот-кей. Т.е изменяем там что нибудь, сохраняем карту, переключаемся на игру альт-табом, нажимаем специальную кнопку и видим изменения.
ScorpioT1000 #9 - 7 лет назад 1
Опишите это в статье
AlakFrost #10 - 7 лет назад 0
Интересно конечно, но пока 1.5 нету...
Харгард #11 - 7 лет назад 0
На неделе немного дополню статью и добавлю главу об изменении инвентаря.
Нашел способ разместить его в почти любом месте экрана на определенной высоте.