Вторник, 24.06.2025, 15:38
Приветствую Вас, Гость | RSS
Форма входа
Меню сайта
Наш опрос
Вы следите за жизнью нашего сайта?
Всего ответов: 31
Главная » 2011 » Июнь » 12 » Делаем свой HUD
20:01
Делаем свой HUD

Вступление

В этой статье мы рассмотрим как сделать HUD (Heads-Up Display) к Вашему моду. Разбирается все довольно-таки детально, так что материал ориентирован на новичка, хотя некоторые знания не помешают (например что такое UCC :)). Скромно надеюсь, что данная статья Вам поможет в нелегком деле модостроительства (или ХУДостроительства :)).

Общие сведения

Все "рисование" на HUD`е (т.е. на экране игрока) осуществляется специальным объектом Canvas (Engine.Canvas), в нем же и содержатся все необходимые функции по рисованию. Если Вы уже изучали Java то возможно понятие Canvas`a (канвы) Вам уже знакомо. Сразу замечу, что по сути дела все рисование сводится к алгоритму:

  1. Установить стиль (атрибуты) рисования (например цвет или прозрачность).
  2. Указать начальную позицию рисуемого объекта на экране.
  3. Нарисовать выбранную текстуру (буквы текстовой строки - это тоже текстуры).

Если Вы не знаете как располагаются координатные оси, вот Вам скрин:

Координатные оси Canvas`a

HUD - это отдельный класс (Engine.HUD), в нем определена функция PostRender:

simulated event PostRender( canvas Canvas );

Именно в этой функции и осуществляется все рисование (в качестве параметра передается ссылка на Canvas - экран игрока). Эта функция вызывается игроком PlayerPawn при каждой перерисовке экрана. Возможно, у Вас возник вопрос "Если я сделаю свой класс наследующий от класса Engine.HUD, каким образом движок будет определять что надо вызывать именно PostRender в моем классе, а не в родительском?" Все просто - в классе GameInfo (собственно это и есть Ваш мод) определена переменная HUDType, значением которой и является ссылка на соответствующий HUD класс. Вывод из всего вышесказанного:

  1. Нам надо сделать класс (например, MyHUD) наследующий от Engine.HUD (или от любого другого его потомка), в котором объявить функцию PostRender.
  2. В функции PostRender при помощи методов Canvas рисовать то, что нам надо (об этом ниже).
  3. Объявить новый класс наследующий от GameInfo и в defaultproperties которого написать строчку типа: HUDType=Class'MyHUD'

Если Вы еще не очень осознали, о чем идет речь - читайте дальше - будет разобран пример учебного HUD`a (глава "Рисуем!").

Замечание по сетевому HUD`у. HUD отображается на клиентской машине, поэтому Вы должны ставить слово simulated в Вашей функции PostRender, разумеется, если Ваш мод не мультиплеерный то simulated писать не надо.

Итак, теперь непосредственно рассмотрим класс Canvas и доступные в нем методы для рисования.

Объект Canvas

Основные свойства (переменные) класса Canvas

  • font Font - шрифт, которым будет отображаться текст, значение переменной Font - название текстуры шрифта. Например: "LadderFonts.UTLadder20".
  • float OrgX, OrgY - координаты точки (0,0), по умолчанию значения переменных OrgX, OrgY естественно равны 0.
  • float ClipX, ClipY - координаты крайне правого нижнего угла экрана. Значения этих переменных меняются в зависимости от текущего разрешения экрана, например, при разрешении 640x480, значение ClipX=640, ClipY=480.
  • float CurX, CurY - текущие координаты для рисования (например, для рисования текстуры с позиции (60,80) значения должны быть CurX=60, CurY=80).
  • byte Style - стиль рисуемого объекта (например эффект прозрачности), возможные значения:
    • (0) STY_None - невидимый объект, заметьте, что объект на самом деле "рисуется", но он не видим на экране.
    • (1) STY_Normal - "обычный" стиль
    • (2) STY_Masked - нулевой цвет (черный) рисуемой текстуры не отображается (для masked текстур).
    • (3) STY_Translucent - эффект прозрачности (за текстурой виден фон).
    • (4) STY_Modulated - каждый пиксель текстуры принимает значение цвета соответствующего пикселя фона.
  • color DrawColor - цвет рисуемого объекта, по умолчанию DrawColor=(127,127,127) (серый цвет). Значения цвета задаются через RGB значения, например:

    Canvas.DrawColor.r = 127; // красная составляющая цвета
    Canvas.DrawColor.g = 127; // зеленая составляющая
    Canvas.DrawColor.b = 127; // голубая составляющая
    

    Заметьте, что если при выводе текстур значение DrawColor не равно белому цвету (255,255,255) то все цвета текстуры претерпевают изменения.

    Влияние DrawColor на отображение текстуры

Функции общего назначения.

  • function SetPos( float X, float Y ) - присваивает CurX=X, CurY=Y. Естественно, что
    SetPos(30,40)
    
    и
    CurX=30;
    CurY=40;
    
    аналогичны по действию, просто первый вариант записывается быстрее : )
  • function SetOrigin( float X, float Y ) - присваивает OrgX=X, OrgY=Y.
  • function SetClip( float X, float Y ) - присваивает ClipX=X, ClipY=Y.
  • event Reset - установка начальных значений (default) всех переменных Canvas (Font,CurX,CurY и т.д.). Полезно когда надо восстановить первоначальные значения переменных одной строкой, вместо того чтобы писать утомительное:

    Font=Canvas.Default.Font;
    CurX=Canvas.Default.CurX
    ...
    

  • function StrLen( coerce string String, out float XL, out float YL ) - возвращает размеры строки String (XL и YL) в зависимости от текущего шрифта.

Функции рисования.

  • function DrawText( coerce string Text, optional bool CR) - выводит строку Text в позицию (CurX,CurY) шрифтом Font и цветом DrawColor.
  • function DrawIcon ( texture Tex, float Scale ) - рисует текстуру Tex в позицию (CurX,CurY) с масштабом Scale.
  • function DrawRectangle ( texture Tex, float RectX, float RectY ) - аналогично DrawIcon, только масштаб по осям X и Y можно указывать различный.
  • function DrawPattern ( texture Tex, float XL, float YL, float Scale ) - рисует повторяющийся "узор" (паттерн) Tex в прямоугольной области, координаты верхнего левого угла этой области (CurX,CurY), а правого нижнего угла (XL,YL)Scale - масштаб самой текстуры Tex, причем в данном случае он реверсивен, т.е. при Scale=2 - текстура в два раза уменьшается, при Scale=0.5 в два раза увеличивается.

    Примечание: в данном случае текстура выводится с позиции (0,0), поэтому если, к примеру, рисовать в центре экрана, то, возможно, что левый верхний угол текстуры не совпадет с левым верхним углом области (смотрите скрин, и Вам все станет ясно)

    Пример DrawPattern - рисование с центра экрана, видно, что верхние левые углы области и текстуры не совпадают:

    Пример DrawPattern

  • function DrawTile( texture Tex, float XL, float YL, float U, float V, float UL, float VL) - собственно это и есть функция на которой основываются DrawIcon,DrawRectangle,DrawPattern. Пояснению параметров отведена отдельная глава.

Специальные функции.

В данной статье эти функции не рассматриваются, чтобы не усложнять материал. Как только Вы разберетесь, как делать свой HUD, эти функции разберете сами без труда.

Рисуем!

Теперь прервемся от пояснений и попытаемся чего-нибудь нарисовать. Создадим свой учебный HUD на котором и поэкспериментируем... : ) Как уже говорилось, рисовать мы должны в функции PostRender(Canvas Canvas) в качестве параметра которой передается ссылка на объект Canvas. Данная функция объявлена в классе HUD (Engine.HUD) и вызывается игроком PlayerPawn при каждой перерисовке HUD`a. Таким образом, нам необходимо создать свой класс который наследует от класса HUD (или любого другого потомка данного класса) и в нем объявить функцию PostRender, в которой и будем рисовать. Однако это еще не все, сделаем свой мод, т.к. в GameInfo есть свойство HUDType которое указывает на используемый HUD. Последовательность создания мода описана ниже, однако, Вы можете загрузить готовый проект.

  1. В каталоге с UT создайте каталог LearnHUD, а в нем каталог Classes
  2. Создайте файл MyGame.uc - это будет наш мод, туда "забейте" следующие строки:

    class MyGame extends DeathMatchPlus;
    
    defaultproperties
    {
     GameName="SUPER PUPER"
     HUDType=Class'MyHUD'
    }
    

  3. Теперь создадим наш HUD

    class MyHUD extends ChallengeHUD;
    
    // Константа для цвета
    var color LightGreen;
    
    // Все рисование производим в этой функции
    // т.к. пример НЕ для сетевой игры, поэтому
    // я не ставлю модификатор simulated
    
    function PostRender(Canvas C) {
    
     local float XL, YL;
    
     // Шрифт
     C.Font = MyFonts.GetBigFont(C.ClipX);
     // Цвет
     C.DrawColor = LightGreen;
     // Стиль
     C.Style = ERenderStyle.STY_NORMAL;
     // Центрируем текст по оси X
     C.bCenter = True;
     // Находим высоту текста чтобы вывести текст по центру оси Y
     C.StrLen("WM",XL,YL);
     // Т.к. bCenter = true, то значение первого
     // параметра SetPos - любое
     C.SetPos(0,(C.ClipY - YL)/2);
     // Собственно рисование текста
     C.DrawText("Hello world!");
    }
    
    defaultproperties
    {
     LightGreen=(R=64,G=255,B=127)
    }
    

    Замечания: стиль вывода и шрифт задается в HUDSetup, наш HUD полностью "глушит" наследуемый ChallengeHUD. Чтобы выводились элементы стандартного HUD`a просто добавьте строку Super.PostRender(C).

  4. Добавьте в UnrealTournament.ini строку:
    [Editor.EditorEngine]
    ...
    EditPackages=LearnHUD
    
  5. Запустите "ucc make".
  6. Создайте LearnHUD.int, в котором должны быть следующие строчки:
    [Public]
    Object=(Name=LearnHUD.MyGame,Class=Class,MetaClass=Botpack.TournamentGameInfo)
    
  7. Теперь собственно все. Запускайте УТ, наш мод и любуйтесь : ) Должно быть что-то типа этого:

Поэкспериментируйте... а затем пойдем дальше.

Шрифты

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

Canvas.Font=Font(DynamicLoadObject("LadderFonts.UTLadder16", class'Font'));

Однако в UnrealTournament размер HUD`a меняется в зависимости от разрешения экрана (в отличие от Unreal), поэтому лучше не указывать шрифт напрямую. В паке Botpack есть класс FontInfo в котором содержатся соответствующие функции, в классе ChallengeHUD определена переменная MyFonts типа FontInfo, так что Вам достаточно обращаться к данной переменной. Вот полный список функции, которыми Вы можете воспользоваться (в качестве параметра Width подставляется ClipX):

  • function font GetHugeFont (float Width)
  • function font GetBigFont (float Width)
  • function font GetMediumFont (float Width)
  • function font GetSmallFont (float Width)
  • function font GetSmallestFont (float Width)
  • function font GetAReallySmallFont (float Width)
  • function font GetACompletelyUnreadableFont (float Width)

Какого размера шрифт возвращают функции я думаю понятно. Вот пример кода:

Canvas.Font=MyFonts.GetMediumFont(Canvas.ClipX);

Масштабирование

Чтение данного раздела относится к тем, кто собирается делать свой HUD наследуя от стандартного ChallengeHUD.

Как уже было упомянуто, в UnrealTournament размер HUD`a меняется в зависимости от текущего разрешения экрана. Однако это еще не все, игрок также может регулировать размеры отдельных элементов экрана, так что при разработке своего HUD`a Вы должны учитывать это. В классе ChallengeHUD определены следующие переменные:

  • float HUDScale - общий масштаб каждого отдельного элемента HUD`a. Устанавливается непосредственно игроком, по умолчанию HUDScale=1.
  • float StatusScale - размер иконки игрока в правом верхнем углу экрана.
  • float WeaponScale - размер панели иконок оружия в нижней части экрана. Если непонятно, смотрите на скрины:

    HUDScale=1 StatusScale=1 WeaponScale=1HUDScale=0.5 StatusScale=1 WeaponScale=1
    HUDScale=1 StatusScale=1 WeaponScale=0.5HUDScale=1 StatusScale=0.5 WeaponScale=1

  • float Scale - общий масштаб, высчитывается в HUDSetup по формуле:
    Scale = (HUDScale * Canvas.ClipX)/1280.0;
    

В общем случае, Вам достаточно иметь дело с параметром Scale, т.е. рассчитывать масштаб и позицию выводимой текстуры как: YourScaleOrLocation*Scale. И еще, перед "рисованием" не забывайте проверять переменную bHideHUD (ее назначение я думаю понятно).

Описание функции DrawTile

native(466) final function DrawTile( texture Tex, float XL, float YL, float U, float V, float UL, float VL );
  • Tex - рисуемая текстура.
  • XL - размер по горизонтали выводимого изображения (в пикселях).
  • YL - размер по вертикали выводимого изображения (в пикселях).
  • U - смещение по горизонтали (в пикселях) выводимой текстуры. Вот пример:
    //
    // XL = 128, UL = 128, U = 0 ("до"):
    // [op]
    //
    // XL = 128, UL = 128, U = 64 ("после"):
    // p][o
    //
    
  • V - смещение по вертикали (в пикселях) выводимой текстуры. Аналогично действию параметра U но по вертикали.
  • UL - какую часть текстуры рисовать (по длине). К примеру, если длина текстуры 128 и UL указать равным 64, то нарисуется только половина текстуры.
  • VL - аналогично UL, только по высоте (вертикали).

Некоторые пояснения. XL,YL определяют область рисования вообще, промасштабировать текстуру можно при помощи UL,VL. А U,V определяют смещение в исходной текстуре при ее рисовании. Если непонятно попробуйте разобраться с этим скринами:

А еще лучше - испытайте сами, зря что ли мы учебный HUD сделали...

Будьте внимательны при указании параметра Tex. Если Вы укажете что-то типа:

Canvas.DrawTile(Texture'UTtech1.Deco.TESTred',256,64,0,0,256,64);

...то UCC будет "ругаться" (Can`t find Texture...) т.к. текстурный пак UTtech1 не загружен при компиляции. Правильнее будет такой вариант:

Canvas.DrawTile(Texture(DynamicLoadObject("UTtech1.Deco.TESTred",class'Texture')),...);

Данное замечание не относится к текстурам включенным в компилируемые классы (при помощи exec), к примеру, так Вы имеете полное право написать:

Canvas.DrawTile(Texture'Botpack.Icons.Use8ball',...);

(Разумеется, имея в виду, что Botpack обрабатывается UCC до Вашего пака).

Хинт

Здесь приведен пример использования Org и Clip переменных. Предположим, Вам понадобилось сделать что-то типа текстовой области, т.е. текст находится в определенных границах (вспомните транслятор в Unreal). При выводе строки UT автоматически переносит ее, если она не помещается в отведенной ей области. Примерно это выглядит так:

|long str|
|ing |
| |

То есть, при достижении строки значения ClipX движок выводит оставшуюся часть строки, начиная с позиции OrgX. Все что нам надо сделать - это поменять значения ClipX и OrgX. И... все. Только не забудьте потом восстановить первоначальные значения Clip и Org переменных.

Заключение

На этом все, основные сведения у Вас есть. Для начала разберитесь с выполнением функций рисования на учебном HUD`е, затем уже можно делать свой HUD. Если у Вас есть какие-то вопросы по материалу этой статьи, либо у Вас что-то не получается - не ленитесь спрашивать.

Удачного Вам ХУДостроительства : ))

Автор

Автор статьи: Shadow
Mail: shadow_m777@mail.ru

Большая часть материала основана на туториале HUD Overview and Canvas functions c сайта CHiMERiC.
Автор: Eater
Mail: lsergey@home.com
Web: http://www.planetunreal.com/nalichronicles/

Просмотров: 4340 | Добавил: Hooligan-Cs | Теги: гемплей, Делаем свой HUD, сделать, Hud, как сделать HUD, как, создать | Рейтинг: 5.0/3
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Мини-чат
500
ADUIOPvhjSFUI
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Всего: 272 
Сегодня:
Вчера:
За неделю: 0
За месяц: 0