Система Flash UI
Материал из CryWiki Russia
DCamer (Обсуждение | вклад) (Новая страница: «The UI Action system allows to setup and control any flash UI element in the flowgraph. For this purpose every flash asset can be defined in an xml file with all ev...») |
DCamer (Обсуждение | вклад) |
||
(7 промежуточных версий не показаны.) | |||
Строка 1: | Строка 1: | ||
- | + | [[Категория:CryEngine_3_Free_SDK:Пользовательский_интерфейс]] | |
+ | Система '''UI Action''' позволяет настраивать и контролировать любые Flash-элементы UI в потоковом графе. | ||
- | + | Для этого каждый Flash-ассет может быть определена в XML-файле со всеми событиями, функциями и переменными, которые должны быть доступны в потоковом графе. | |
- | == | + | == Дочерние статьи == |
+ | * [[Система Flash UI/Функции|Список функций LUA]] | ||
+ | * [[Система Flash UI/Элементы UI как динамические текстуры|Элементы UI как динамические текстуры]] | ||
+ | * [[Система Flash UI/Локализация UI|Локализация UI]] | ||
+ | * [[Система Flash UI/Использование FlashUI из CPP|Использование FlashUI из CPP]] | ||
- | + | == Настройка XML для Flash-ассета == | |
+ | Система '''Flash UI''' считывает все XML-файлы, которые находятся в '''Game/Libs/UI/UIElements''' и создаёт потоковые ноды для контролирования Flash-ассетов. | ||
- | + | Откройте существующий XML-файл или создайте новый, чтобы определить новый '''UIElement'''. | |
- | + | Основное определение Flash-ассета: | |
- | {{Код|заголовок=hud.xml|блок=<source lang="xml"><UIElements name="HudElements"> <!-- | + | {{Код|заголовок=hud.xml|блок=<source lang="xml"><UIElements name="HudElements"> <!-- название группы для этого элемента --> |
- | <!-- | + | <!-- определение элемента UI под названием "HUD" --> |
<UIElement name="HUD"> | <UIElement name="HUD"> | ||
- | <!-- | + | <!-- GFX/SWF-файл для этого элемента UI --> |
<GFx file="HUD.gfx" layer="1"> | <GFx file="HUD.gfx" layer="1"> | ||
- | <!-- | + | <!-- режим выравнивание этого элемента --> |
<Constraints> | <Constraints> | ||
<Align mode="dynamic" halign="center" valign="center" scale="1" max="1" /> | <Align mode="dynamic" halign="center" valign="center" scale="1" max="1" /> | ||
Строка 24: | Строка 30: | ||
</GFx> | </GFx> | ||
- | <!-- | + | <!-- доступные функции--> |
<functions> | <functions> | ||
</functions> | </functions> | ||
- | <!-- | + | <!-- доступные события, которые вызываются Flash-ассетом --> |
<events> | <events> | ||
</events> | </events> | ||
- | <!-- | + | <!-- доступные переменные--> |
<variables> | <variables> | ||
</variables> | </variables> | ||
- | <!-- | + | <!-- доступные массивы --> |
<arrays> | <arrays> | ||
</arrays> | </arrays> | ||
- | <!-- | + | <!-- доступные мувиклипы --> |
<movieclips> | <movieclips> | ||
</movieclips> | </movieclips> | ||
Строка 46: | Строка 52: | ||
</UIElement> | </UIElement> | ||
- | <!-- | + | <!-- определение другого элемента UI под названием "LoadingScreen" --> |
<UIElement name="LoadingScreen"> | <UIElement name="LoadingScreen"> | ||
... | ... | ||
Строка 54: | Строка 60: | ||
</source>}} | </source>}} | ||
+ | === Функции === | ||
+ | Функции, которые должны будут вызывать извне, нужна определить в списке '''<functions>''' элемента. | ||
- | + | Например, функция ActionScript, для установки полосы здоровья: | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
{{Код|заголовок=ActionScript|блок=<source lang="actionscript">function setHealth(iHealth:Number):void | {{Код|заголовок=ActionScript|блок=<source lang="actionscript">function setHealth(iHealth:Number):void | ||
{ | { | ||
- | // | + | // установка полосы здоровья |
} | } | ||
</source>}} | </source>}} | ||
- | + | Может быть определена в XML так: | |
{{Код|заголовок=hud.xml|блок=<source lang="xml"><function name="SetHealth" funcname="setHealth"> | {{Код|заголовок=hud.xml|блок=<source lang="xml"><function name="SetHealth" funcname="setHealth"> | ||
Строка 74: | Строка 78: | ||
</source>}} | </source>}} | ||
- | + | Где '''name="…"''' — название функции, отображаемое в потоковом графе, а '''funcname="…"''' — название функции в самом ActionScript. | |
- | + | Система автоматически создаст нод, чтобы вызывать эту функцию. | |
[[Файл:Function_node.png]] | [[Файл:Function_node.png]] | ||
- | + | {{Примечание|Кроме того, можно определить функции, которые находятся не в корневом пространстве Flash-файла, например: | |
- | + | {{Код|bgcolor=orange|color=white|заголовок=hud.xml|блок=<source lang="xml"><function name="SetHealth" funcname="myHealthMc.mysubmc.setHealth"> | |
- | {{Код|заголовок=hud.xml|блок=<source lang="xml"><function name="SetHealth" funcname="myHealthMc.mysubmc.setHealth"> | + | |
<param name="Health" desc="Players current health"/> | <param name="Health" desc="Players current health"/> | ||
</function> | </function> | ||
- | </source>}} | + | </source>}}}} |
- | + | ||
- | + | ||
- | + | === События === | |
+ | Чтобы получить уведомления о каком-либо взаимодействии с пользователем, например, если была нажата кнопка, можно определить события в списке '''<events>'''. Чтобы вызвать срабатывание события в коде '''ActionScript''', необходимо вызвать ''fscommand(«строкаКоманда»)''. Эти ''fscommands'' перехватываются движком. | ||
- | + | Например, в функции '''onPress''' у кнопки, вы можете вызвать ''fscommand'' со строкой '''«onMyButtonPressed»''' и несколькими аргументами. | |
{{Код|заголовок=ActionScript|блок=<source lang="actionscript">myButton.onPress = function() | {{Код|заголовок=ActionScript|блок=<source lang="actionscript">myButton.onPress = function() | ||
Строка 98: | Строка 100: | ||
args.push(argument1); | args.push(argument1); | ||
args.push(argument2); | args.push(argument2); | ||
- | fscommand( | + | fscommand("onMyButtonPressed", args); |
} | } | ||
</source>}} | </source>}} | ||
- | + | Чтобы перехватить это событие, добавьте тег '''<event>''' в список '''<events>''': | |
{{Код|заголовок=hud.xml|блок=<source lang="xml"><event name="OnButton1" fscommand="onMyButtonPressed"> | {{Код|заголовок=hud.xml|блок=<source lang="xml"><event name="OnButton1" fscommand="onMyButtonPressed"> | ||
<param name="Arg1" desc="Some argument"/> | <param name="Arg1" desc="Some argument"/> | ||
Строка 109: | Строка 111: | ||
</source>}} | </source>}} | ||
- | + | Система создаст нод для перехвата этого события. | |
[[Файл:Event_node.png]] | [[Файл:Event_node.png]] | ||
- | === | + | === Переменные, массивы и мувиклипы === |
- | + | Доступ к массиву или переменной также могут быть определены в XML-файле. | |
- | + | ||
- | + | Просто добавьте тег '''<variable>''' в список '''<variables>''', тег '''<array>''' в список '''<arrays>''' или тег '''<movieclip>''' в список '''<movieclips>'''. | |
{{Код|заголовок=hud.xml|блок=<source lang="xml"><variables> | {{Код|заголовок=hud.xml|блок=<source lang="xml"><variables> | ||
Строка 134: | Строка 135: | ||
</source>}} | </source>}} | ||
- | + | Чтобы получить или задать переменные, выберите в выпадающем списке потоковый нод '''UI:Variable:Var''' или '''UI:Variable:Array'''. | |
[[Файл:Variable_nodes.png]] | [[Файл:Variable_nodes.png]] | ||
- | + | {{Примечание|Массивы представляют собой строки разделённые запятой.}} | |
- | + | Вы также можете получить доступ к определённым мувиклипам через потоковые ноды. | |
[[Файл:Mc_gotoandplay.png]] | [[Файл:Mc_gotoandplay.png]] | ||
- | == | + | == Отображение/скрытие и настройка GFX-файлов == |
+ | Чтобы отобразить или скрыть Flash-ассет используйте нод '''UI:Display:Display'''. Вы можете выбрать элемент в выпадающем списке. | ||
- | + | Чтобы настроить поведение и ограничения используйте ноды '''UI:Display:Config''' и '''UI:Display:Constraints''' соответственно. | |
- | + | ||
- | + | ||
[[Файл:Config_node.png]] | [[Файл:Config_node.png]] | ||
[[Файл:Constraints_node.png]] | [[Файл:Constraints_node.png]] | ||
- | + | Также можно инициализировать все эти настройки в XML-файле. | |
{{Код|заголовок=hud.xml|блок=<source lang="xml"><UIElement name="HUD" mouseevents="1" keyevents="1" cursor="1" console_mouse="1" console_cursor="1"> | {{Код|заголовок=hud.xml|блок=<source lang="xml"><UIElement name="HUD" mouseevents="1" keyevents="1" cursor="1" console_mouse="1" console_cursor="1"> | ||
<GFx file="HUD.gfx" layer="1" alpha="0.5"> | <GFx file="HUD.gfx" layer="1" alpha="0.5"> | ||
- | <!-- | + | <!-- режим выравнивание этого элемента --> |
<Constraints> | <Constraints> | ||
<Align mode="fullscreen" /> | <Align mode="fullscreen" /> | ||
Строка 171: | Строка 171: | ||
</source>}} | </source>}} | ||
- | === | + | === Конфигурация === |
+ | {{BTS|mouseevents|desc=0=отключено, 1=включено, если включено события мыши будут пересылаться в файле Flash (щелчки и перемещения мыши).}} | ||
- | + | {{BTS|cursor|desc=0=отключено, 1=включено, если включено аппаратный курсор мыши будет видимым пока отображен Flash-элемент.}} | |
- | 0= | + | |
- | + | {{BTS|keyevents|desc=0=отключено, 1=включено, если включено ключи событий будут пересылаться в Flash-элемент.}} | |
- | 0= | + | |
- | + | {{BTS|console_mouse|desc=0=отключено, 1=включено, если включено контроллер будет работать как мышь на консоли (аналоговый стик). Только если включено '''mouseevents'''.}} | |
- | 0= | + | |
- | + | {{BTS|console_cursor|desc=0=отключено, 1=включено, если включено аппаратный курсор мыши также будет отображён на консоле. Только если включено '''cursor'''.}} | |
- | 0= | + | |
- | + | {{BTS|layer|desc=от 0 до ''n'', определяет, в каком порядке будут отображены элементы (если отображен более чем один Flash-элемент).}} | |
- | 0 | + | |
- | + | {{BTS|alpha|desc=от 0 до 1, альфа фона Flash-элемента.}} | |
- | 0 | + | |
- | + | === Ограничения === | |
- | + | Доступно три режима размещения ассетов на экране: | |
- | = | + | {{BTS|"fixed"|desc=В этом режим Flash-ассет отображается в фиксированном положение, определённым значениями '''top''', '''left''', '''width''' и '''height'''.}} |
- | + | {{BTS|"dynamic"|desc=В этом режим ассет выравнивается якорями. Для вертикального выравнивания возможны '''top''', '''center''' или '''bottom''', для горизонтального выравнивания возможны '''left''', '''center''' или '''right'''.}} | |
+ | Если '''scale''' равно '''1''', элемент будет максимально масштабирован, не деформируя пропорции. Если '''scale''' равно '''0''', Flash-ассет не будет масштабироваться. | ||
- | + | Если '''max''' равно '''1''', то элемент будет максимизирован, так, что 100% экрана будут закрыты (это может привести к тому, что некоторые части элемента выйдут за экран) В противном случае асстер будет подогнан под экран, возможны некоторые незакрытые пространства слева/справа или сверху/снизу. | |
- | + | ||
- | + | {{BTS|"fullscreen"|desc=В этом режим окно проекции ассета равно окну проекции рендера. Если '''scale''' равно '''1''' ассет растягивается по размеру всего экрана, в ином случае нет.}} | |
- | + | ||
- | + | == Экземпляры элементов == | |
- | + | У каждого нода есть порт '''InstanceID'''. Благодаря этому идентификатору экземпляра, у вас может быть более одного экземпляра любого Flash-ассета. Порт '''InstanceID''' любого нода UI определяет, на какой экземпляр будет влиять этот нод. Если вы используете нод с новым идентификатором экземпляра, автоматически будет создан новый экземпляр этого Flash-ассета. Если вы использует '''-1''' в качестве идентификатора экземпляра, нод будет влиять на все экземпляры этого Flash-элемента. | |
- | + | == Полезные функции == | |
- | + | Доступно несколько специальных функции '''ActionScript''', которые автоматически вызываются системой UI. | |
- | + | Эти функции могут быть определены в '''ActionScript''' в корневом пространстве и не нужно определять в XML-файле. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
=== Функции === | === Функции === | ||
- | ==== | + | ==== Функции ActionScript ==== |
+ | ;cry_onSetup:Если эта функция существует, она вызывается однократно когда GFX/SWF-файл загружен движком. | ||
+ | <source lang="actionscript">function cry_onSetup(_bIsConsole) // истинно если запущено на консоле, ложь если на ПК</source> | ||
- | + | ;cry_onShow:Если эта функция существует, она вызывается однократно когда GFX/SWF-файл показан. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
<source lang="actionscript">function cry_onShow()</source> | <source lang="actionscript">function cry_onShow()</source> | ||
- | + | ;cry_onHide:Если эта функция существует, она вызывается однократно когда GFX/SWF-файл скрыт. | |
- | + | ||
<source lang="actionscript">function cry_onHide()</source> | <source lang="actionscript">function cry_onHide()</source> | ||
- | + | ;cry_onResize:Если эта функция существует, она вызывается однократно когда разрешение движка изменено. | |
- | + | ||
<source lang="actionscript">function cry_onResize(_intWidth, _intHeight)</source> | <source lang="actionscript">function cry_onResize(_intWidth, _intHeight)</source> | ||
- | + | ;cry_onBack:Если эта функция существует, она вызывается однократно, если игрок нажал кнопку '''Back''' на контроллере. | |
- | + | ||
<source lang="actionscript">function cry_onBack()</source> | <source lang="actionscript">function cry_onBack()</source> | ||
- | + | ;cry_requestHide:Эта функция вызывается, если сработал порт '''RequestHide''' у нода '''UI:Display:Display''' (или через код/Lua). Может быть использовано для плавного исчезновения элемента. | |
- | + | ||
<source lang="actionscript">function cry_requestHide()</source> | <source lang="actionscript">function cry_requestHide()</source> | ||
- | ==== | + | ==== FSCommand ==== |
+ | Доступно несколько строк FSCommand, которые могут быть вызваны вашим ActionScript. | ||
- | + | ;cry_hideElement:Если FSCommand выполнен с этой строкой, он укажет системе UI скрыть элемент. | |
- | + | <source lang="actionscript">fsCommand("cry_hideElement");</source> | |
- | + | ||
- | + | ||
- | <source lang="actionscript"> | + | |
- | + | ||
- | + | ||
- | + | === Пример === | |
+ | Плавное появление/исчезновение элемента UI. | ||
- | <source lang="actionscript">// | + | <source lang="actionscript">// создаём функцию onEnterFrame для плавного появления корневого элемента (если показан элемент UI) |
function cry_onShow() | function cry_onShow() | ||
{ | { | ||
Строка 271: | Строка 247: | ||
else | else | ||
{ | { | ||
- | // | + | // очищаем функцию onEnterFrame |
onEnterFrame = function() {}; | onEnterFrame = function() {}; | ||
} | } | ||
Строка 277: | Строка 253: | ||
} | } | ||
- | // | + | // создаём функцию onEnterFrame для плавного исчезновения корневого элемента (если запрошено системой UI) |
function cry_requestHide() | function cry_requestHide() | ||
{ | { | ||
Строка 288: | Строка 264: | ||
else | else | ||
{ | { | ||
- | // | + | // очищаем функцию onEnterFrame и уведомляем систему UI, что этот элемент больше не надо отрисовывать. |
onEnterFrame = function() {}; | onEnterFrame = function() {}; | ||
fscommand("cry_hideElement"); | fscommand("cry_hideElement"); | ||
Строка 295: | Строка 271: | ||
} | } | ||
</source> | </source> | ||
- | + | Теперь вы можете делать, чтобы элемент плавно появлялся/исчезал при срабатывании про '''show'''/'''requestHide''' у нода '''UI:Display:Display'''. | |
[[Файл:fg_fadeElement.png]] | [[Файл:fg_fadeElement.png]] | ||
- | == UI | + | == Потоковые графы UI == |
+ | Чтобы создать новый потоковый граф для UI, просто откройте '''Flow Graph''' и выберите '''File->New UI Action…'''. | ||
- | + | Все действия UI размещены в потоковых графах, а все XML-файлы должны быть сохранены в '''Game/Libs/UI/UIActions'''. | |
- | + | ||
- | + | ||
[[Файл:FG_workspace.png]] | [[Файл:FG_workspace.png]] | ||
- | + | {{Примечание|Все действия UI сохранены отдельно от уровня. Их нужно сохранять через '''File->Save''' в меню потокового графа. '''Убедитесь, что сохраняете каждый раз после изменений!'''}} | |
- | + | Все потоковые ноды для UI в списке компонентов UI. | |
[[Файл:FGfg_components.png]] | [[Файл:FGfg_components.png]] | ||
- | === | + | === Пример === |
- | + | Пример простого потокового графа для показа/скрытия экрана загрузки и определения названия уровня и полосы прогресса. | |
- | + | ||
[[Файл:example_fg.png]] | [[Файл:example_fg.png]] | ||
- | + | Связанный элемент определён в '''Game/Libs/UI/UIElements/Menus.xml''': | |
{{Код|заголовок=Menus.xml|блок=<source lang="xml"><UIElement name="LoadingScreen"> | {{Код|заголовок=Menus.xml|блок=<source lang="xml"><UIElement name="LoadingScreen"> | ||
Строка 337: | Строка 311: | ||
</source>}} | </source>}} | ||
- | == UI | + | == UI Action == |
- | + | Иногда бывает нужно вызывать сложные UI Action (действия UI) несколько раз без перестраивания всякий раз всего графа. | |
- | + | ||
- | + | Для этих целей можно создать UI Action с помощью нодов '''UI:Action:Start''' и '''UI:Action:End'''. Эти ноды находятся в разделе '''UI:Action'''. | |
- | + | Название потокового графа определяет название действия. | |
- | + | Нод '''UI:Action:Control''' позволяет начать UI Action и получить уведомления, если действие было начато или остановлено. | |
- | + | Также можно провести несколько аргументов UI Action через нод '''UI:Action:Control'''. | |
- | + | В качестве примера, UI Action для отображения USM-видео: | |
[[Файл:ui_action.png]] | [[Файл:ui_action.png]] | ||
- | + | Это действие может быть использовано, например, для воспроизведения видеоролика при входе в '''Proximity Trigger''': | |
[[Файл:ui_action_2.png]] | [[Файл:ui_action_2.png]] | ||
- | + | {{Примечание|Вы можете управлять любым действием UI из любого потокового графа. Если вы отключите UI Action, будет отключен полностью весь потоковый граф (а не только ноды между нодами начала и конца). Также можно испоользоватьь ноды '''StartAction''' и '''EndAction''' более одного раза в одном потоковом графе. Каждый нод '''StartAction''' сработает, если действие начато, и первый достигший нода '''EndAction''' инициирует порт '''OnEnd''' у любого нода '''UI:Action:Control''', который «прослушивает» потоковый граф.}} | |
- | + | == Система LUA и Flash UI == | |
- | == LUA | + | Также можно управлять системой UI через LUA. |
- | + | * [[Flash UI/Функции|Список функций LUA]] | |
- | + | ||
- | [ | + | |
=== Example === | === Example === | ||
- | + | <source lang="lua">// Отображаем элемент UI | |
- | <source lang="lua">// | + | |
UIAction.ShowElement("MyUIElement", 0); | UIAction.ShowElement("MyUIElement", 0); | ||
- | // | + | // Вызываем ActionScript |
UIAction.CallFunction("MyUIElement", 0, "Foo", "paramStr1", "paramStr2", 123, 12.3, false); | UIAction.CallFunction("MyUIElement", 0, "Foo", "paramStr1", "paramStr2", 123, 12.3, false); | ||
- | // | + | // задаём переменную |
UIAction.SetVariable("MyUIElement", 0, "MyVariable", 23); | UIAction.SetVariable("MyUIElement", 0, "MyVariable", 23); | ||
- | // | + | // получаем переменную |
local var1 = UIAction.GetVariable("MyUIElement", 0, "MyVariable"); | local var1 = UIAction.GetVariable("MyUIElement", 0, "MyVariable"); | ||
if (var1) then | if (var1) then | ||
Строка 390: | Строка 360: | ||
UIAction.SetArray("MyUIElement", 0, "MyArray", newValues); | UIAction.SetArray("MyUIElement", 0, "MyArray", newValues); | ||
- | // | + | // получаем массив |
local values = UIAction.GetArray("MyUIElement", 0, "MyArray"); | local values = UIAction.GetArray("MyUIElement", 0, "MyArray"); | ||
local value; | local value; | ||
Строка 400: | Строка 370: | ||
</source> | </source> | ||
- | == | + | == Коммуникация между C++ и потоковым графом UI == |
- | + | Вы можете просто создать свои собственные потоковые ноды и использовать их вызова/получения функций/событий UI. Подробная информация в статье [[Создание нового потокового нода]]». | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | == Система UI Event == | |
+ | В системе UI есть система событий, которая также используется для коммуникации между C++ и потоковым графом UI. | ||
- | + | Система событий предоставляет легкий метод для определения нодов функций и событий и перехват их из C++. | |
- | + | === Ноды функций === | |
+ | Ноды функций доступны для всех потоковых графов и позволяют вызывать код C++. | ||
- | + | Создайте новый файл '''.h''' и назовите его '''UIFunctions.h''': | |
{{Код|заголовок=UIFunctions.h|блок=<source lang="cpp">#ifndef __UIFunctions_H__ | {{Код|заголовок=UIFunctions.h|блок=<source lang="cpp">#ifndef __UIFunctions_H__ | ||
Строка 442: | Строка 409: | ||
</source>}} | </source>}} | ||
- | + | Создайте новый файл '''.cpp''' и назовите его '''UIFunctions.cpp''': | |
{{Код|заголовок=UIFunctions.cpp|блок=<source lang="cpp">#include "StdAfx.h" | {{Код|заголовок=UIFunctions.cpp|блок=<source lang="cpp">#include "StdAfx.h" | ||
Строка 452: | Строка 419: | ||
if (gEnv->pFlashUI) | if (gEnv->pFlashUI) | ||
{ | { | ||
- | // | + | // создаём новую систему событий под названием "Game" |
- | // | + | // вводим ноды eEST_UI_TO_SYSTEM; для этой системы событий из раздела UI:Functions |
- | // | + | // регистрируем как листенер событий |
m_pGameEvents = gEnv->pFlashUI->CreateEventSystem( "Game", IUIEventSystem::eEST_UI_TO_SYSTEM ); | m_pGameEvents = gEnv->pFlashUI->CreateEventSystem( "Game", IUIEventSystem::eEST_UI_TO_SYSTEM ); | ||
m_pGameEvents->RegisterListener( this ); | m_pGameEvents->RegisterListener( this ); | ||
- | // | + | // создаём новое описание функции для "Foo" |
SUIEventDesc fooDesc( "Foo", "Foo", "Call a function named foo" ); | SUIEventDesc fooDesc( "Foo", "Foo", "Call a function named foo" ); | ||
- | // | + | // добавляем описание параметра "Arg1" к описанию функции |
fooDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); | fooDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); | ||
- | // | + | // регистрируем описание функции в диспачере |
m_Dispatcher.RegisterEvent( m_pGameEvents, fooDesc, &CUIFunctions::OnFoo ); | m_Dispatcher.RegisterEvent( m_pGameEvents, fooDesc, &CUIFunctions::OnFoo ); | ||
- | // | + | // создаём другое описание функции для "Bar" |
SUIEventDesc barDesc( "Bar", "Bar", "Call a function named bar" ); | SUIEventDesc barDesc( "Bar", "Bar", "Call a function named bar" ); | ||
barDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); | barDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); | ||
Строка 482: | Строка 449: | ||
void CUIFunctions::OnEvent( const SUIEvent& event ) | void CUIFunctions::OnEvent( const SUIEvent& event ) | ||
{ | { | ||
- | // | + | // используем диспачер для диспача события, чтобы откорректировать функцию |
m_Dispatcher.Dispatch( this, event ); | m_Dispatcher.Dispatch( this, event ); | ||
} | } | ||
Строка 496: | Строка 463: | ||
} | } | ||
- | // | + | // делаем что-нибудь |
} | } | ||
Строка 516: | Строка 483: | ||
} | } | ||
- | // | + | // делаем что-нибудь |
} | } | ||
</source>}} | </source>}} | ||
- | + | Откройте '''Game.h''', объявляем свой класс и добавляем частный член в '''CGame''': | |
{{Код|заголовок=Game.h|блок=<source lang="cpp">#ifndef __GAME_H__ | {{Код|заголовок=Game.h|блок=<source lang="cpp">#ifndef __GAME_H__ | ||
Строка 547: | Строка 514: | ||
</source>}} | </source>}} | ||
- | + | Откройте '''Game.cpp''' инициализируйте '''m_pUIFunctions''' с '''NULL''' в конструкторе, удалить '''m_pUIFunctions''' в деконструкторе и создайте объект '''CUIFunction''' в конце функции инициализирования. | |
{{Код|заголовок=Game.cpp|блок=<source lang="cpp">#include "StdAfx.h" | {{Код|заголовок=Game.cpp|блок=<source lang="cpp">#include "StdAfx.h" | ||
Строка 580: | Строка 547: | ||
... | ... | ||
</source>}} | </source>}} | ||
- | { | + | {{Примечание|Очень важно создать все ваши классы, которые использует система событий UI, прежде, чем вызван '''CompleteInit'''.}} |
- | + | Этот в результате создаст два новых нода '''UI:Functions:Game:Foo''' и '''UI:Functions:Game:Bar'''. | |
[[Файл:evsys_fct_node.png]] | [[Файл:evsys_fct_node.png]] | ||
- | + | Если порт '''send''' инициирован, он вызовет код C++ в '''UIFunctions.cpp'''. | |
- | + | ||
- | + | ||
- | + | === Ноды событий === | |
- | + | Ноды событий очень похожи на ноды функций. Они используются для отправки событий из C++ в любой потоковый граф UI. | |
+ | Например, вы можете создать одноэлементный класс для вызова событий из любой части вашего evenкода. | ||
- | + | Создайте H-файл '''UIGameEvents.h''': | |
{{Код|заголовок=UIGameEvents.h|блок=<source lang="cpp">#ifndef __UIGameEvents_H__ | {{Код|заголовок=UIGameEvents.h|блок=<source lang="cpp">#ifndef __UIGameEvents_H__ | ||
Строка 603: | Строка 569: | ||
{ | { | ||
public: | public: | ||
- | // | + | // получаем доступ к экземпляру |
static CUIGameEvents* GetInstance() | static CUIGameEvents* GetInstance() | ||
{ | { | ||
Строка 610: | Строка 576: | ||
} | } | ||
- | // | + | // инициализируем игровые события |
void Init(); | void Init(); | ||
- | // | + | // события |
enum EUIGameEvents | enum EUIGameEvents | ||
{ | { | ||
Строка 632: | Строка 598: | ||
</source>}} | </source>}} | ||
- | + | Создайте CPP-файл '''UIGameEvents.cpp''': | |
{{Код|заголовок=UIGameEvents.cpp|блок=<source lang="cpp">#include "StdAfx.h" | {{Код|заголовок=UIGameEvents.cpp|блок=<source lang="cpp">#include "StdAfx.h" | ||
Строка 641: | Строка 607: | ||
if (gEnv->pFlashUI) | if (gEnv->pFlashUI) | ||
{ | { | ||
- | // | + | // создаём новую систему событий под названием "Game" |
- | // | + | // вводим ноды eEST_UI_TO_SYSTEM; для этой системы событий из раздела UI:Events |
m_pGameEvents = gEnv->pFlashUI->CreateEventSystem( "Game", IUIEventSystem::eEST_SYSTEM_TO_UI ); | m_pGameEvents = gEnv->pFlashUI->CreateEventSystem( "Game", IUIEventSystem::eEST_SYSTEM_TO_UI ); | ||
- | // | + | // создаём новое описание события для "Foo" |
SUIEventDesc fooDesc( "Foo", "Foo", "Event named foo" ); | SUIEventDesc fooDesc( "Foo", "Foo", "Event named foo" ); | ||
- | // | + | // добавляем описание параметра "Arg1" к описанию события |
fooDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); | fooDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); | ||
- | // | + | // регистрируем событие в системе событий и связываем id с перечислителем события |
m_EventMap[ eUIGE_FooEvent ] = m_pGameEvents->RegisterEvent( fooDesc ); | m_EventMap[ eUIGE_FooEvent ] = m_pGameEvents->RegisterEvent( fooDesc ); | ||
- | // | + | // создаём другое описание события для "Bar" |
SUIEventDesc barDesc( "Bar", "Bar", "Event named bar" ); | SUIEventDesc barDesc( "Bar", "Bar", "Event named bar" ); | ||
barDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); | barDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); | ||
Строка 662: | Строка 628: | ||
void CUIGameEvents::SendEvent( EUIGameEvents event, const SUIArguments& args ) | void CUIGameEvents::SendEvent( EUIGameEvents event, const SUIArguments& args ) | ||
{ | { | ||
- | // | + | // отправляем событием |
if (m_pGameEvents) | if (m_pGameEvents) | ||
{ | { | ||
Строка 670: | Строка 636: | ||
</source>}} | </source>}} | ||
- | + | Откройте '''Game.cpp''', включите «'''UIGameEvents.h'''» и добавьте в конец функции '''Init''': | |
{{Код|заголовок=Game.cpp|блок=<source lang="cpp">bool CGame::Init(IGameFramework *pFramework) | {{Код|заголовок=Game.cpp|блок=<source lang="cpp">bool CGame::Init(IGameFramework *pFramework) | ||
Строка 680: | Строка 646: | ||
</source>}} | </source>}} | ||
- | + | Код создаст два нода для потокового графа: | |
[[Файл:evsys_evt_node.png]] | [[Файл:evsys_evt_node.png]] | ||
- | + | Теперь вы можете вызвать из любой части вашего кода функцию '''SendEvent''' для вызова, к примеру, нода '''UI:Events:Game:Bar''': | |
<source lang="cpp">int arg1 = 12; | <source lang="cpp">int arg1 = 12; |
Текущая версия на 16:17, 9 марта 2012
Система UI Action позволяет настраивать и контролировать любые Flash-элементы UI в потоковом графе.
Для этого каждый Flash-ассет может быть определена в XML-файле со всеми событиями, функциями и переменными, которые должны быть доступны в потоковом графе.
Содержание |
Дочерние статьи
- Список функций LUA
- Элементы UI как динамические текстуры
- Локализация UI
- Использование FlashUI из CPP
Настройка XML для Flash-ассета
Система Flash UI считывает все XML-файлы, которые находятся в Game/Libs/UI/UIElements и создаёт потоковые ноды для контролирования Flash-ассетов.
Откройте существующий XML-файл или создайте новый, чтобы определить новый UIElement.
Основное определение Flash-ассета:
<UIElements name="HudElements"> <!-- название группы для этого элемента --> <!-- определение элемента UI под названием "HUD" --> <UIElement name="HUD"> <!-- GFX/SWF-файл для этого элемента UI --> <GFx file="HUD.gfx" layer="1"> <!-- режим выравнивание этого элемента --> <Constraints> <Align mode="dynamic" halign="center" valign="center" scale="1" max="1" /> </Constraints> </GFx> <!-- доступные функции--> <functions> </functions> <!-- доступные события, которые вызываются Flash-ассетом --> <events> </events> <!-- доступные переменные--> <variables> </variables> <!-- доступные массивы --> <arrays> </arrays> <!-- доступные мувиклипы --> <movieclips> </movieclips> </UIElement> <!-- определение другого элемента UI под названием "LoadingScreen" --> <UIElement name="LoadingScreen"> ... </UIElement> </UIElements>
Функции
Функции, которые должны будут вызывать извне, нужна определить в списке <functions> элемента.
Например, функция ActionScript, для установки полосы здоровья:
function setHealth(iHealth:Number):void { // установка полосы здоровья }
Может быть определена в XML так:
<function name="SetHealth" funcname="setHealth"> <param name="Health" desc="Players current health"/> </function>
Где name="…" — название функции, отображаемое в потоковом графе, а funcname="…" — название функции в самом ActionScript.
Система автоматически создаст нод, чтобы вызывать эту функцию.
Примечание:
Кроме того, можно определить функции, которые находятся не в корневом пространстве Flash-файла, например:
<function name="SetHealth" funcname="myHealthMc.mysubmc.setHealth"> <param name="Health" desc="Players current health"/> </function>
События
Чтобы получить уведомления о каком-либо взаимодействии с пользователем, например, если была нажата кнопка, можно определить события в списке <events>. Чтобы вызвать срабатывание события в коде ActionScript, необходимо вызвать fscommand(«строкаКоманда»). Эти fscommands перехватываются движком.
Например, в функции onPress у кнопки, вы можете вызвать fscommand со строкой «onMyButtonPressed» и несколькими аргументами.
myButton.onPress = function() { var args:Array = new Array(); args.push(argument1); args.push(argument2); fscommand("onMyButtonPressed", args); }
Чтобы перехватить это событие, добавьте тег <event> в список <events>:
<event name="OnButton1" fscommand="onMyButtonPressed"> <param name="Arg1" desc="Some argument"/> <param name="Arg2" desc="Another argument"/> </event>
Система создаст нод для перехвата этого события.
Переменные, массивы и мувиклипы
Доступ к массиву или переменной также могут быть определены в XML-файле.
Просто добавьте тег <variable> в список <variables>, тег <array> в список <arrays> или тег <movieclip> в список <movieclips>.
<variables> <variable name="SomeVariable" varname="someVariable"/> <variable name="TextField" varname="_root.myTextfield.text"/> </variables> <arrays> <array name="SomeArray" varname="_root.mc2.someArray"/> </arrays> <movieclips> <movieclip name="MovieClip1" instancename="_root.Mc1"/> <movieclip name="MovieClip2" instancename="_root.Mc1.subMc"/> </movieclips>
Чтобы получить или задать переменные, выберите в выпадающем списке потоковый нод UI:Variable:Var или UI:Variable:Array.
Примечание:
Массивы представляют собой строки разделённые запятой.
Вы также можете получить доступ к определённым мувиклипам через потоковые ноды.
Отображение/скрытие и настройка GFX-файлов
Чтобы отобразить или скрыть Flash-ассет используйте нод UI:Display:Display. Вы можете выбрать элемент в выпадающем списке.
Чтобы настроить поведение и ограничения используйте ноды UI:Display:Config и UI:Display:Constraints соответственно.
Также можно инициализировать все эти настройки в XML-файле.
<UIElement name="HUD" mouseevents="1" keyevents="1" cursor="1" console_mouse="1" console_cursor="1"> <GFx file="HUD.gfx" layer="1" alpha="0.5"> <!-- режим выравнивание этого элемента --> <Constraints> <Align mode="fullscreen" /> <!-- <Align mode="dynamic" halign="center" valign="center" scale="1" max="1" /> --> <!-- <Align mode="fixed" /> --> <!-- <Position top="20" left="20" width="200" height="200" /> --> </Constraints> </GFx> … </UIElement>
Конфигурация
• mouseevents• cursor
• keyevents
• console_mouse
• console_cursor
• layer
• alpha
Ограничения
Доступно три режима размещения ассетов на экране:
• "fixed"• "dynamic"
Если scale равно 1, элемент будет максимально масштабирован, не деформируя пропорции. Если scale равно 0, Flash-ассет не будет масштабироваться.
Если max равно 1, то элемент будет максимизирован, так, что 100% экрана будут закрыты (это может привести к тому, что некоторые части элемента выйдут за экран) В противном случае асстер будет подогнан под экран, возможны некоторые незакрытые пространства слева/справа или сверху/снизу.
• "fullscreen"Экземпляры элементов
У каждого нода есть порт InstanceID. Благодаря этому идентификатору экземпляра, у вас может быть более одного экземпляра любого Flash-ассета. Порт InstanceID любого нода UI определяет, на какой экземпляр будет влиять этот нод. Если вы используете нод с новым идентификатором экземпляра, автоматически будет создан новый экземпляр этого Flash-ассета. Если вы использует -1 в качестве идентификатора экземпляра, нод будет влиять на все экземпляры этого Flash-элемента.
Полезные функции
Доступно несколько специальных функции ActionScript, которые автоматически вызываются системой UI.
Эти функции могут быть определены в ActionScript в корневом пространстве и не нужно определять в XML-файле.
Функции
Функции ActionScript
- cry_onSetup
- Если эта функция существует, она вызывается однократно когда GFX/SWF-файл загружен движком.
function cry_onSetup(_bIsConsole) // истинно если запущено на консоле, ложь если на ПК
- cry_onShow
- Если эта функция существует, она вызывается однократно когда GFX/SWF-файл показан.
function cry_onShow()
- cry_onHide
- Если эта функция существует, она вызывается однократно когда GFX/SWF-файл скрыт.
function cry_onHide()
- cry_onResize
- Если эта функция существует, она вызывается однократно когда разрешение движка изменено.
function cry_onResize(_intWidth, _intHeight)
- cry_onBack
- Если эта функция существует, она вызывается однократно, если игрок нажал кнопку Back на контроллере.
function cry_onBack()
- cry_requestHide
- Эта функция вызывается, если сработал порт RequestHide у нода UI:Display:Display (или через код/Lua). Может быть использовано для плавного исчезновения элемента.
function cry_requestHide()
FSCommand
Доступно несколько строк FSCommand, которые могут быть вызваны вашим ActionScript.
- cry_hideElement
- Если FSCommand выполнен с этой строкой, он укажет системе UI скрыть элемент.
fsCommand("cry_hideElement");
Пример
Плавное появление/исчезновение элемента UI.
// создаём функцию onEnterFrame для плавного появления корневого элемента (если показан элемент UI) function cry_onShow() { _root._alpha = 0; onEnterFrame = function() { if (_root._alpha < 100) { _root._alpha++; } else { // очищаем функцию onEnterFrame onEnterFrame = function() {}; } } } // создаём функцию onEnterFrame для плавного исчезновения корневого элемента (если запрошено системой UI) function cry_requestHide() { onEnterFrame = function() { if (_root._alpha > 0) { _root._alpha--; } else { // очищаем функцию onEnterFrame и уведомляем систему UI, что этот элемент больше не надо отрисовывать. onEnterFrame = function() {}; fscommand("cry_hideElement"); } } }
Теперь вы можете делать, чтобы элемент плавно появлялся/исчезал при срабатывании про show/requestHide у нода UI:Display:Display.
Потоковые графы UI
Чтобы создать новый потоковый граф для UI, просто откройте Flow Graph и выберите File->New UI Action….
Все действия UI размещены в потоковых графах, а все XML-файлы должны быть сохранены в Game/Libs/UI/UIActions.
Примечание:
Все действия UI сохранены отдельно от уровня. Их нужно сохранять через File->Save в меню потокового графа. Убедитесь, что сохраняете каждый раз после изменений!
Все потоковые ноды для UI в списке компонентов UI.
Пример
Пример простого потокового графа для показа/скрытия экрана загрузки и определения названия уровня и полосы прогресса.
Связанный элемент определён в Game/Libs/UI/UIElements/Menus.xml:
<UIElement name="LoadingScreen"> <GFx file="LoadingScreen.gfx" layer="2" alpha="1" > <Constraints> <Align mode="fullscreen" /> </Constraints> </GFx> <variables> <variable name="Percent" varname="LoadingPanel.Percent.text"/> <variable name="LevelName" varname="LoadingPanel.Level.text"/> </variables> </UIElement>
UI Action
Иногда бывает нужно вызывать сложные UI Action (действия UI) несколько раз без перестраивания всякий раз всего графа.
Для этих целей можно создать UI Action с помощью нодов UI:Action:Start и UI:Action:End. Эти ноды находятся в разделе UI:Action.
Название потокового графа определяет название действия.
Нод UI:Action:Control позволяет начать UI Action и получить уведомления, если действие было начато или остановлено.
Также можно провести несколько аргументов UI Action через нод UI:Action:Control.
В качестве примера, UI Action для отображения USM-видео:
Это действие может быть использовано, например, для воспроизведения видеоролика при входе в Proximity Trigger:
Примечание:
Вы можете управлять любым действием UI из любого потокового графа. Если вы отключите UI Action, будет отключен полностью весь потоковый граф (а не только ноды между нодами начала и конца). Также можно испоользоватьь ноды StartAction и EndAction более одного раза в одном потоковом графе. Каждый нод StartAction сработает, если действие начато, и первый достигший нода EndAction инициирует порт OnEnd у любого нода UI:Action:Control, который «прослушивает» потоковый граф.
Система LUA и Flash UI
Также можно управлять системой UI через LUA.
Example
// Отображаем элемент UI UIAction.ShowElement("MyUIElement", 0); // Вызываем ActionScript UIAction.CallFunction("MyUIElement", 0, "Foo", "paramStr1", "paramStr2", 123, 12.3, false); // задаём переменную UIAction.SetVariable("MyUIElement", 0, "MyVariable", 23); // получаем переменную local var1 = UIAction.GetVariable("MyUIElement", 0, "MyVariable"); if (var1) then Log("Var1: %d", var1); end // set array local newValues = { "val1", "val2", "val3", }; UIAction.SetArray("MyUIElement", 0, "MyArray", newValues); // получаем массив local values = UIAction.GetArray("MyUIElement", 0, "MyArray"); local value; if (values) then for i,value in ipairs(values) do Log("Value: %s", value); end end
Коммуникация между C++ и потоковым графом UI
Вы можете просто создать свои собственные потоковые ноды и использовать их вызова/получения функций/событий UI. Подробная информация в статье Создание нового потокового нода».
Система UI Event
В системе UI есть система событий, которая также используется для коммуникации между C++ и потоковым графом UI.
Система событий предоставляет легкий метод для определения нодов функций и событий и перехват их из C++.
Ноды функций
Ноды функций доступны для всех потоковых графов и позволяют вызывать код C++.
Создайте новый файл .h и назовите его UIFunctions.h:
#ifndef __UIFunctions_H__ #define __UIFunctions_H__ #include <IFlashUI.h> class CUIFunctions : public IUIEventListener { public: CUIFunctions(); ~CUIFunctions(); // IUIEventListener virtual void OnEvent( const SUIEvent& event ); // ~IUIEventListener private: SUIEventHelper<CUIFunctions> m_Dispatcher; IUIEventSystem* m_pGameEvents; void OnFoo( const SUIEvent& event ); void OnBar( const SUIEvent& event ); }; #endif
Создайте новый файл .cpp и назовите его UIFunctions.cpp:
#include "StdAfx.h" #include "UIFunctions.h" CUIFunctions::CUIFunctions() : m_pGameEvents(NULL) { if (gEnv->pFlashUI) { // создаём новую систему событий под названием "Game" // вводим ноды eEST_UI_TO_SYSTEM; для этой системы событий из раздела UI:Functions // регистрируем как листенер событий m_pGameEvents = gEnv->pFlashUI->CreateEventSystem( "Game", IUIEventSystem::eEST_UI_TO_SYSTEM ); m_pGameEvents->RegisterListener( this ); // создаём новое описание функции для "Foo" SUIEventDesc fooDesc( "Foo", "Foo", "Call a function named foo" ); // добавляем описание параметра "Arg1" к описанию функции fooDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); // регистрируем описание функции в диспачере m_Dispatcher.RegisterEvent( m_pGameEvents, fooDesc, &CUIFunctions::OnFoo ); // создаём другое описание функции для "Bar" SUIEventDesc barDesc( "Bar", "Bar", "Call a function named bar" ); barDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); barDesc.Params.push_back( SUIParameterDesc( "Arg2", "Arg2", "Second Arg" ) ); m_Dispatcher.RegisterEvent( m_pGameEvents, barDesc, &CUIFunctions::OnBar ); } } CUIFunctions::~CUIFunctions() { if ( m_pGameEvents ) m_pGameEvents->UnregisterListener( this ); } void CUIFunctions::OnEvent( const SUIEvent& event ) { // используем диспачер для диспача события, чтобы откорректировать функцию m_Dispatcher.Dispatch( this, event ); } void CUIFunctions::OnFoo( const SUIEvent& event ) { int arg1 = 0; if ( !event.args.GetArg(0, arg1) ) { CryLogAlways("Foo: argument 1 has wrong type (should be int)"); return; } // делаем что-нибудь } void CUIFunctions::OnBar( const SUIEvent& event ) { bool arg1 = false; float arg2 = 0; if ( !event.args.GetArg(0, arg1) ) { CryLogAlways("Foo: argument 1 has wrong type (should be bool)"); return; } if ( !event.args.GetArg(1, arg2) ) { CryLogAlways("Foo: argument 2 has wrong type (should be float)"); return; } // делаем что-нибудь }
Откройте Game.h, объявляем свой класс и добавляем частный член в CGame:
#ifndef __GAME_H__ #define __GAME_H__ ... class CUIFunctions; ... class CGame : public IGame, public IGameFrameworkListener, public ILevelSystemListener { ... private: ... CUIFunctions * m_pUIFunctions; ... } ...
Откройте Game.cpp инициализируйте m_pUIFunctions с NULL в конструкторе, удалить m_pUIFunctions в деконструкторе и создайте объект CUIFunction в конце функции инициализирования.
#include "StdAfx.h" #include "Game.h" ... #include "UIFunctions.h" CGame::CGame() ... { m_pUIFunctions = NULL; } CGame::~CGame() { ... SAFE_DELETE(m_pUIFunctions); } ... bool CGame::Init(IGameFramework *pFramework) { ... if (m_ pUIFunctions == NULL) { m_ pUIFunctions = new CUIFunctions(); } } ...
Примечание:
Очень важно создать все ваши классы, которые использует система событий UI, прежде, чем вызван CompleteInit.
Этот в результате создаст два новых нода UI:Functions:Game:Foo и UI:Functions:Game:Bar.
Если порт send инициирован, он вызовет код C++ в UIFunctions.cpp.
Ноды событий
Ноды событий очень похожи на ноды функций. Они используются для отправки событий из C++ в любой потоковый граф UI. Например, вы можете создать одноэлементный класс для вызова событий из любой части вашего evenкода.
Создайте H-файл UIGameEvents.h:
#ifndef __UIGameEvents_H__ #define __UIGameEvents_H__ #include <IFlashUI.h> class CUIGameEvents { public: // получаем доступ к экземпляру static CUIGameEvents* GetInstance() { static CUIGameEvents inst; return &inst; } // инициализируем игровые события void Init(); // события enum EUIGameEvents { eUIGE_FooEvent, eUIGE_BarEvent, }; void SendEvent( EUIGameEvents event, const SUIArguments& args ); private: CUIGameEvents() : m_pGameEvents(NULL) {}; ~CUIGameEvents() {}; IUIEventSystem* m_pGameEvents; std::map<EUIGameEvents, uint> m_EventMap; }; #endif
Создайте CPP-файл UIGameEvents.cpp:
#include "StdAfx.h" #include "UIGameEvents.h" void CUIGameEvents::Init() { if (gEnv->pFlashUI) { // создаём новую систему событий под названием "Game" // вводим ноды eEST_UI_TO_SYSTEM; для этой системы событий из раздела UI:Events m_pGameEvents = gEnv->pFlashUI->CreateEventSystem( "Game", IUIEventSystem::eEST_SYSTEM_TO_UI ); // создаём новое описание события для "Foo" SUIEventDesc fooDesc( "Foo", "Foo", "Event named foo" ); // добавляем описание параметра "Arg1" к описанию события fooDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); // регистрируем событие в системе событий и связываем id с перечислителем события m_EventMap[ eUIGE_FooEvent ] = m_pGameEvents->RegisterEvent( fooDesc ); // создаём другое описание события для "Bar" SUIEventDesc barDesc( "Bar", "Bar", "Event named bar" ); barDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) ); barDesc.Params.push_back( SUIParameterDesc( "Arg2", "Arg2", "Second Arg" ) ); m_EventMap[ eUIGE_BarEvent ] = m_pGameEvents->RegisterEvent( barDesc ); } } void CUIGameEvents::SendEvent( EUIGameEvents event, const SUIArguments& args ) { // отправляем событием if (m_pGameEvents) { m_pGameEvents->SendEvent( SUIEvent(m_EventMap[event], args) ); } }
Откройте Game.cpp, включите «UIGameEvents.h» и добавьте в конец функции Init:
bool CGame::Init(IGameFramework *pFramework) { ... CUIGameEvents::GetInstance()->Init(); } ...
Код создаст два нода для потокового графа:
Теперь вы можете вызвать из любой части вашего кода функцию SendEvent для вызова, к примеру, нода UI:Events:Game:Bar:
int arg1 = 12; float arg2 = 1.4f; SUIArguments args; args.AddArgument( arg1 ); args.AddArgument( arg2 ); CUIGameEvents::GetInstance()->SendEvent( CUIGameEvents::eUIGE_BarEvent, args );