Система Flash UI

Материал из CryWiki Russia

(Различия между версиями)
Перейти к: навигация, поиск
 
(6 промежуточных версий не показаны.)
Строка 1: Строка 1:
 +
[[Категория:CryEngine_3_Free_SDK:Пользовательский_интерфейс]]
Система '''UI Action''' позволяет настраивать и контролировать любые Flash-элементы UI в потоковом графе.
Система '''UI Action''' позволяет настраивать и контролировать любые Flash-элементы UI в потоковом графе.
Для этого каждый Flash-ассет может быть определена в XML-файле со всеми событиями, функциями и переменными, которые должны быть доступны в потоковом графе.
Для этого каждый Flash-ассет может быть определена в XML-файле со всеми событиями, функциями и переменными, которые должны быть доступны в потоковом графе.
-
== Настройка XML для Flash-ассета ==
+
== Дочерние статьи ==
 +
* [[Система Flash UI/Функции|Список функций LUA]]
 +
* [[Система Flash UI/Элементы UI как динамические текстуры|Элементы UI как динамические текстуры]]
 +
* [[Система Flash UI/Локализация UI|Локализация UI]]
 +
* [[Система Flash UI/Использование FlashUI из CPP|Использование FlashUI из CPP]]
-
Система '''Flash UI''' считывает все XML-файлы, которые находятся в'''Game/Libs/UI/UIElements''' и создаёт потоковые ноды для контролирования Flash-ассетов.
+
== Настройка XML для Flash-ассета ==
 +
Система '''Flash UI''' считывает все XML-файлы, которые находятся в '''Game/Libs/UI/UIElements''' и создаёт потоковые ноды для контролирования Flash-ассетов.
Откройте существующий XML-файл или создайте новый, чтобы определить новый '''UIElement'''.
Откройте существующий XML-файл или создайте новый, чтобы определить новый '''UIElement'''.
Строка 53: Строка 59:
</UIElements>
</UIElements>
</source>}}
</source>}}
-
 
=== Функции ===
=== Функции ===
-
 
Функции, которые должны будут вызывать извне, нужна определить в списке '''<functions>''' элемента.
Функции, которые должны будут вызывать извне, нужна определить в списке '''<functions>''' элемента.
Строка 74: Строка 78:
</source>}}
</source>}}
-
Где '''name="…"''' название функции, отображаемое в потоковом графе, а '''funcname="…"''' название функции в самом ActionScript.
+
Где '''name="…"''' — название функции, отображаемое в потоковом графе, а '''funcname="…"''' — название функции в самом ActionScript.
Система автоматически создаст нод, чтобы вызывать эту функцию.
Система автоматически создаст нод, чтобы вызывать эту функцию.
Строка 87: Строка 91:
=== События ===
=== События ===
-
Чтобы получить уведомления о каком-либо взаимодействии с пользователем, например, если была нажата кнопка, можно определить события в списке '''<events>'''. Чтобы вызвать срабатывание события в коде '''ActionScript''', необходимо вызвать ''fscommand("строкаКоманда")''. Эти ''fscommands'' перехватываются движком.
+
Чтобы получить уведомления о каком-либо взаимодействии с пользователем, например, если была нажата кнопка, можно определить события в списке '''<events>'''. Чтобы вызвать срабатывание события в коде '''ActionScript''', необходимо вызвать ''fscommand(«строкаКоманда»)''. Эти ''fscommands'' перехватываются движком.
-
Например, в функции '''onPress''' у кнопки, вы можете вызвать ''fscommand'' со строкой '''"onMyButtonPressed"''' и несколькими аргументами.
+
Например, в функции '''onPress''' у кнопки, вы можете вызвать ''fscommand'' со строкой '''«onMyButtonPressed»''' и несколькими аргументами.
{{Код|заголовок=ActionScript|блок=<source lang="actionscript">myButton.onPress = function()
{{Код|заголовок=ActionScript|блок=<source lang="actionscript">myButton.onPress = function()
Строка 112: Строка 116:
=== Переменные, массивы и мувиклипы ===
=== Переменные, массивы и мувиклипы ===
-
 
Доступ к массиву или переменной также могут быть определены в XML-файле.
Доступ к массиву или переменной также могут быть определены в XML-файле.
Строка 132: Строка 135:
</source>}}
</source>}}
-
To get or set a variable select the variable in the dropdown list of the *UI:Variable:Var* or *UI:Variable:Array* flownode.
+
Чтобы получить или задать переменные, выберите в выпадающем списке потоковый нод '''UI:Variable:Var''' или '''UI:Variable:Array'''.
[[Файл:Variable_nodes.png]]
[[Файл:Variable_nodes.png]]
-
*Note:* Arrays are comma separated strings.
+
{{Примечание|Массивы представляют собой строки разделённые запятой.}}
-
You can also access your defined MovieClips via FlowNodes.
+
Вы также можете получить доступ к определённым мувиклипам через потоковые ноды.
[[Файл:Mc_gotoandplay.png]]
[[Файл:Mc_gotoandplay.png]]
-
== Display / hide and setup gfx files ==
+
== Отображение/скрытие и настройка GFX-файлов ==
 +
Чтобы отобразить или скрыть Flash-ассет используйте нод '''UI:Display:Display'''. Вы можете выбрать элемент в выпадающем списке.
-
To show or hide a flash asset use the *UI:Display:Display* node. You can select the element in the dropdown list.
+
Чтобы настроить поведение и ограничения используйте ноды '''UI:Display:Config''' и '''UI:Display:Constraints''' соответственно.
-
 
+
-
To setup the behavior and the constraints use the *UI:Display:Constraints* and *UI:Display:Config* nodes.
+
[[Файл:Config_node.png]]
[[Файл:Config_node.png]]
[[Файл:Constraints_node.png]]
[[Файл:Constraints_node.png]]
-
It is also possible to initialize all of those settings in the xml file.
+
Также можно инициализировать все эти настройки в 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">
-
     <!-- the align mode of this element -->
+
     <!-- режим выравнивание этого элемента -->
     <Constraints>
     <Constraints>
       <Align mode="fullscreen" />
       <Align mode="fullscreen" />
Строка 169: Строка 171:
</source>}}
</source>}}
-
=== Configuration ===
+
=== Конфигурация ===
-
 
+
{{BTS|mouseevents|desc=0=отключено, 1=включено, если включено события мыши будут пересылаться в файле Flash (щелчки и перемещения мыши).}}
-
* *mouseevents*
+
-
0=disable, 1=enabled, if enabled mouse events are send to the flash file (mouse-clicks and movement)
+
-
 
+
-
* *cursor*
+
-
0=disabled, 1=enabled, if enabled a hardware mouse cursor is visible while the flash element is displayed.
+
-
 
+
-
* *keyevents*
+
-
0=disabled, 1=enabled, if enabled keyevents are send to the flash element.
+
-
 
+
-
* *console_mouse*
+
-
0=disabled, 1=enabled, if enabled the controller works as a mouse on console (thumb-stick). Only if *mouseevents* are enabled.
+
-
* *console_cursor*
+
{{BTS|cursor|desc=0=отключено, 1=включено, если включено аппаратный курсор мыши будет видимым пока отображен Flash-элемент.}}
-
0=diabled, 1=enabled, if enabled a hardware cursor is displayed on console as well. Only if *cursor* is enabled.
+
-
* *layer*
+
{{BTS|keyevents|desc=0=отключено, 1=включено, если включено ключи событий будут пересылаться в Flash-элемент.}}
-
0 to n, defines in which order the elements are displayed (if more than one flash element is visible).
+
-
* *alpha*
+
{{BTS|console_mouse|desc=0=отключено, 1=включено, если включено контроллер будет работать как мышь на консоли (аналоговый стик). Только если включено '''mouseevents'''.}}
-
0 to 1, the background alpha of the flash element.
+
-
=== Constraints ===
+
{{BTS|console_cursor|desc=0=отключено, 1=включено, если включено аппаратный курсор мыши также будет отображён на консоле. Только если включено '''cursor'''.}}
-
There are three modes to place the asset on the screen:
+
{{BTS|layer|desc=от 0 до ''n'', определяет, в каком порядке будут отображены элементы (если отображен более чем один Flash-элемент).}}
-
* *"fixed"*
+
{{BTS|alpha|desc=от 0 до 1, альфа фона Flash-элемента.}}
-
in this mode the flash asset is displayed on a fixed position, defined by a top, left, width and height value.
+
-
* *"dynamic"*
+
=== Ограничения ===
-
this mode aligns the asset on anchors. For vertical alignment it is possible to align the flash element at the "top", "center" or "bottom", for horizontal alignment to the "left", "center" or "right" of the screen.
+
Доступно три режима размещения ассетов на экране:
-
If *scale* is "1" it tries to scale the element to the maximum without deforming the aspect ratio. If *scale* is set to "0", it will not scale the flash asset.
+
{{BTS|"fixed"|desc=В этом режим Flash-ассет отображается в фиксированном положение, определённым значениями '''top''', '''left''', '''width''' и '''height'''.}}
-
If *max* is set to "1" it will maximize the element so that 100% of the screen is covered (this might cause that some parts of the element are cut-off) otherwise the asset will fit to the screen with maybe some uncovered space on the left/right or top/bottom side.
+
-
* *"fullscreen"*
+
{{BTS|"dynamic"|desc=В этом режим ассет выравнивается якорями. Для вертикального выравнивания возможны '''top''', '''center''' или '''bottom''', для горизонтального выравнивания возможны '''left''', '''center''' или '''right'''.}}
-
In this mode the viewport of the asset is same as the render viewport. If *scale* is set to "1" the asset is stretched to fit the complete screen, otherwise not.
+
Если '''scale''' равно '''1''', элемент будет максимально масштабирован, не деформируя пропорции. Если '''scale''' равно '''0''', Flash-ассет не будет масштабироваться.
-
== Instantiation of Elements ==
+
Если '''max''' равно '''1''', то элемент будет максимизирован, так, что 100% экрана будут закрыты (это может привести к тому, что некоторые части элемента выйдут за экран) В противном случае асстер будет подогнан под экран, возможны некоторые незакрытые пространства слева/справа или сверху/снизу.
-
Each node has the *"InstanceID"* port. With this instance ID you can have more than one instance of any flash asset. The *"InstanceID"* port of any UI node defines which instance should be affected by this node. If you use a node with a new instance ID it will automaticly create the new instance of this flash asset. If you use "-1" as the instance ID, the node will affect all instances of this flash element.
+
{{BTS|"fullscreen"|desc=В этом режим окно проекции ассета равно окну проекции рендера. Если '''scale''' равно '''1''' ассет растягивается по размеру всего экрана, в ином случае нет.}}
-
== Helpful functions ==
+
== Экземпляры элементов ==
 +
У каждого нода есть порт '''InstanceID'''. Благодаря этому идентификатору экземпляра, у вас может быть более одного экземпляра любого Flash-ассета. Порт '''InstanceID''' любого нода UI определяет, на какой экземпляр будет влиять этот нод. Если вы используете нод с новым идентификатором экземпляра, автоматически будет создан новый экземпляр этого Flash-ассета. Если вы использует '''-1''' в качестве идентификатора экземпляра, нод будет влиять на все экземпляры этого Flash-элемента.
-
There are some special *actionscript* functions that are automatically called by the UI system.
+
== Полезные функции ==
 +
Доступно несколько специальных функции '''ActionScript''', которые автоматически вызываются системой UI.
-
These functions can be defined in the rootspace of your *actionscript* and don’t need to be defined in the xml file.
+
Эти функции могут быть определены в '''ActionScript''' в корневом пространстве и не нужно определять в XML-файле.
=== Функции ===
=== Функции ===
-
==== Actionscript functions ====
+
==== Функции ActionScript ====
 +
;cry_onSetup:Если эта функция существует, она вызывается однократно когда GFX/SWF-файл загружен движком.
 +
<source lang="actionscript">function cry_onSetup(_bIsConsole) // истинно если запущено на консоле, ложь если на ПК</source>
-
*cry_onSetup*
+
;cry_onShow:Если эта функция существует, она вызывается однократно когда GFX/SWF-файл показан.
-
If this function exists, it is called once the gfx/swf file is loaded by the engine.
+
-
<source lang="actionscript">function cry_onSetup(_bIsConsole) // true if running on console, false for pc</source>
+
-
 
+
-
*cry_onShow*
+
-
If this function exists, it is called once the gfx/swf file is shown up.
+
<source lang="actionscript">function cry_onShow()</source>
<source lang="actionscript">function cry_onShow()</source>
-
*cry_onHide*
+
;cry_onHide:Если эта функция существует, она вызывается однократно когда GFX/SWF-файл скрыт.
-
If this function exists, it is called once the gfx/swf file is hided.
+
<source lang="actionscript">function cry_onHide()</source>
<source lang="actionscript">function cry_onHide()</source>
-
*cry_onResize*
+
;cry_onResize:Если эта функция существует, она вызывается однократно когда разрешение движка изменено.
-
If this function exists, it is called once the resolution of the engine has changed.
+
<source lang="actionscript">function cry_onResize(_intWidth, _intHeight)</source>
<source lang="actionscript">function cry_onResize(_intWidth, _intHeight)</source>
-
*cry_onBack*
+
;cry_onBack:Если эта функция существует, она вызывается однократно, если игрок нажал кнопку '''Back''' на контроллере.
-
If this function exists, it is called once if the player pressed the back button on the controller.
+
<source lang="actionscript">function cry_onBack()</source>
<source lang="actionscript">function cry_onBack()</source>
-
*cry_requestHide*
+
;cry_requestHide:Эта функция вызывается, если сработал порт '''RequestHide''' у нода '''UI:Display:Display''' (или через код/Lua). Может быть использовано для плавного исчезновения элемента.
-
This function is called if the "RequestHide" port was triggered on the UI:Display:Display Node (or via code / lua). Can be used to fade out elements.
+
<source lang="actionscript">function cry_requestHide()</source>
<source lang="actionscript">function cry_requestHide()</source>
-
==== fscommands ====
+
==== FSCommand ====
 +
Доступно несколько строк FSCommand, которые могут быть вызваны вашим ActionScript.
-
There are some fscommand strings that can be called within your actionscript.
+
;cry_hideElement:Если FSCommand выполнен с этой строкой, он укажет системе UI скрыть элемент.
 +
<source lang="actionscript">fsCommand("cry_hideElement");</source>
-
*cry_hideElement*
+
=== Пример ===
-
If a fscommand is executed with this string, it tells the UI System to hide the element.
+
Плавное появление/исчезновение элемента UI.
-
<source lang="actionscript">fscommand("cry_hideElement");</source>
+
-
=== Example ===
+
<source lang="actionscript">// создаём функцию onEnterFrame для плавного появления корневого элемента (если показан элемент UI)
-
 
+
-
Fade UI Element in / out.
+
-
 
+
-
<source lang="actionscript">// create onEnterFrame function to fade-in the root element (if UI Element is shown up)
+
function cry_onShow()
function cry_onShow()
{
{
Строка 269: Строка 247:
       else
       else
       {
       {
-
         // clear onEnterFrame function
+
         // очищаем функцию onEnterFrame
         onEnterFrame = function() {};
         onEnterFrame = function() {};
       }
       }
Строка 275: Строка 253:
}
}
-
// create onEnterFrame function to fade-out the root element (if requested by UI System)
+
// создаём функцию onEnterFrame для плавного исчезновения корневого элемента (если запрошено системой UI)
function cry_requestHide()
function cry_requestHide()
{
{
Строка 286: Строка 264:
       else
       else
       {
       {
-
         // clear onEnterFrame function and notify UI-System that this element does not need to be drawn anymore.
+
         // очищаем функцию onEnterFrame и уведомляем систему UI, что этот элемент больше не надо отрисовывать.
         onEnterFrame = function() {};
         onEnterFrame = function() {};
         fscommand("cry_hideElement");
         fscommand("cry_hideElement");
Строка 293: Строка 271:
}
}
</source>
</source>
-
You can now fade in/out the element by triggering the port show / requestHide if the UI:Display:Display Node.
+
Теперь вы можете делать, чтобы элемент плавно появлялся/исчезал при срабатывании про '''show'''/'''requestHide''' у нода '''UI:Display:Display'''.
[[Файл:fg_fadeElement.png]]
[[Файл:fg_fadeElement.png]]
-
== UI Flowgraphs ==
+
== Потоковые графы UI ==
-
 
+
Чтобы создать новый потоковый граф для UI, просто откройте '''Flow Graph''' и выберите '''File->New UI Action…'''.
-
To create a new flowgraph for the UI just open the *Flowgraph* and choose “File->New UI Action…”.
+
-
All UI Actions are located in the *Flow Graphs* list and the xml files needs to be saved in '''Game/Libs/UI/UIActions'''.
+
Все действия UI размещены в потоковых графах, а все XML-файлы должны быть сохранены в '''Game/Libs/UI/UIActions'''.
[[Файл:FG_workspace.png]]
[[Файл:FG_workspace.png]]
-
*Note:* All UI actions are saved separate from the level. They need to be saved via File->Save in the flowgraph menu. *Make sure to save every time you did some changes\!*
+
{{Примечание|Все действия UI сохранены отдельно от уровня. Их нужно сохранять через '''File->Save''' в меню потокового графа. '''Убедитесь, что сохраняете каждый раз после изменений!'''}}
-
You find all flownodes for the UI in the component list unter UI.
+
Все потоковые ноды для UI в списке компонентов UI.
[[Файл:FGfg_components.png]]
[[Файл:FGfg_components.png]]
-
=== Example ===
+
=== Пример ===
-
 
+
Пример простого потокового графа для показа/скрытия экрана загрузки и определения названия уровня и полосы прогресса.
-
This example shows a simple flowgraph to show/hide a loading screen and setup the level name and a progress value.
+
[[Файл:example_fg.png]]
[[Файл:example_fg.png]]
-
The associated element is defined in '''Game/Libs/UI/UIElements/Menus.xml''':
+
Связанный элемент определён в '''Game/Libs/UI/UIElements/Menus.xml''':
{{Код|заголовок=Menus.xml|блок=<source lang="xml"><UIElement name="LoadingScreen">
{{Код|заголовок=Menus.xml|блок=<source lang="xml"><UIElement name="LoadingScreen">
Строка 335: Строка 311:
</source>}}
</source>}}
-
== UI Actions ==
+
== UI Action ==
 +
Иногда бывает нужно вызывать сложные UI Action (действия UI) несколько раз без перестраивания всякий раз всего графа.
-
Sometimes it is helpful to trigger a complex UI Action several times without rebuilding the whole graph every time.
+
Для этих целей можно создать UI Action с помощью нодов '''UI:Action:Start''' и '''UI:Action:End'''. Эти ноды находятся в разделе '''UI:Action'''.
-
For this purpose it is possible to create UI Actions with a *“UI:Action:Start”* and *“*{*}UI:Action:End{*}*”* node. You will find this nodes under UI:Action.
+
Название потокового графа определяет название действия.
-
The Name of the Flowgraph defines the Name of the Action.
+
Нод '''UI:Action:Control''' позволяет начать UI Action и получить уведомления, если действие было начато или остановлено.
-
The *“*{*}UI:Action:Control{*}*”* node allows to start an UI Action and receive notifications if an action was started or stopped.
+
Также можно провести несколько аргументов UI Action через нод '''UI:Action:Control'''.
-
It is also possible to pass several arguments to an UIAction via the *“*{*}UI:Action:Control{*}*”* node.
+
В качестве примера, UI Action для отображения USM-видео:
-
 
+
-
As an example the UIAction to display a USM Video file:
+
[[Файл:ui_action.png]]
[[Файл:ui_action.png]]
-
This action can be used e.g. to play a movie on enter a proximity trigger:
+
Это действие может быть использовано, например, для воспроизведения видеоролика при входе в '''Proximity Trigger''':
[[Файл:ui_action_2.png]]
[[Файл:ui_action_2.png]]
-
*Note:* You can control any UI action from any flowgraph. If you disable an UI Action, the complete flowgraph will be disabled (not only the Nodes between the start and end node). It is also possible to use the *StartAction* and *EndAction* notes more than once per flowgraph. Every *StartAction* node will be triggered if the action is started and the first reached *EndAction* node will trigger the OnEnd port of any *UI:Action:Control* node which is listening to the flowgraph.
+
{{Примечание|Вы можете управлять любым действием UI из любого потокового графа. Если вы отключите UI Action, будет отключен полностью весь потоковый граф (а не только ноды между нодами начала и конца). Также можно испоользоватьь ноды '''StartAction''' и '''EndAction''' более одного раза в одном потоковом графе. Каждый нод '''StartAction''' сработает, если действие начато, и первый достигший нода '''EndAction''' инициирует порт '''OnEnd''' у любого нода '''UI:Action:Control''', который «прослушивает» потоковый граф.}}
-
 
+
== Система LUA и Flash UI ==
-
== LUA and Flash UI System ==
+
Также можно управлять системой UI через LUA.
-
 
+
* [[Flash UI/Функции|Список функций LUA]]
-
It is also possible to control the UI System via LUA.
+
-
[List of LUA functions|Flash UI LUA functions]
+
=== Example ===
=== Example ===
-
 
+
<source lang="lua">// Отображаем элемент UI
-
<source lang="lua">// Display UI Element
+
UIAction.ShowElement("MyUIElement", 0);
UIAction.ShowElement("MyUIElement", 0);
-
// Call actionscript
+
// Вызываем ActionScript
UIAction.CallFunction("MyUIElement", 0, "Foo", "paramStr1", "paramStr2", 123, 12.3, false);
UIAction.CallFunction("MyUIElement", 0, "Foo", "paramStr1", "paramStr2", 123, 12.3, false);
-
// set variable
+
// задаём переменную
UIAction.SetVariable("MyUIElement", 0, "MyVariable", 23);
UIAction.SetVariable("MyUIElement", 0, "MyVariable", 23);
-
// get variable
+
// получаем переменную
local var1 = UIAction.GetVariable("MyUIElement", 0, "MyVariable");
local var1 = UIAction.GetVariable("MyUIElement", 0, "MyVariable");
if (var1) then
if (var1) then
Строка 388: Строка 360:
UIAction.SetArray("MyUIElement", 0, "MyArray", newValues);
UIAction.SetArray("MyUIElement", 0, "MyArray", newValues);
-
// get array
+
// получаем массив
local values = UIAction.GetArray("MyUIElement", 0, "MyArray");
local values = UIAction.GetArray("MyUIElement", 0, "MyArray");
local value;
local value;
Строка 398: Строка 370:
</source>
</source>
-
== Communication between C+\+ and UI flowgraph ==
+
== Коммуникация между C++ и потоковым графом UI ==
 +
Вы можете просто создать свои собственные потоковые ноды и использовать их вызова/получения функций/событий UI. Подробная информация в статье [[Создание нового потокового нода]]».
-
You can just create your own custom flownodes and use them to trigger/receive UI functions/events. More information in the [Creating a New Flow Node] topic.
+
== Система UI Event ==
 +
В системе UI есть система событий, которая также используется для коммуникации между C++ и потоковым графом UI.
-
== UI Event System ==
+
Система событий предоставляет легкий метод для определения нодов функций и событий и перехват их из C++.
-
The UI System comes with an event system which can also used to communicate between C+\+ and the UI flowgraph.
+
=== Ноды функций ===
 +
Ноды функций доступны для всех потоковых графов и позволяют вызывать код C++.
-
The event system provides an easy way to define function and event nodes and handle them in C++.
+
Создайте новый файл '''.h''' и назовите его '''UIFunctions.h''':
-
 
+
-
=== Function nodes ===
+
-
 
+
-
Function nodes are available to all flowgraphs and provide an easy way to call C+\+ code.
+
-
 
+
-
Create a new .h file and name it *UIFunctions.h*
+
{{Код|заголовок=UIFunctions.h|блок=<source lang="cpp">#ifndef __UIFunctions_H__
{{Код|заголовок=UIFunctions.h|блок=<source lang="cpp">#ifndef __UIFunctions_H__
Строка 440: Строка 409:
</source>}}
</source>}}
-
Create a new .cpp file and name it *UIFunctions.cpp*
+
Создайте новый файл '''.cpp''' и назовите его '''UIFunctions.cpp''':
{{Код|заголовок=UIFunctions.cpp|блок=<source lang="cpp">#include "StdAfx.h"
{{Код|заголовок=UIFunctions.cpp|блок=<source lang="cpp">#include "StdAfx.h"
Строка 450: Строка 419:
     if (gEnv->pFlashUI)
     if (gEnv->pFlashUI)
     {
     {
-
         // create a new event system called "Game"
+
         // создаём новую систему событий под названием "Game"
-
         // type is eEST_UI_TO_SYSTEM; nodes for this event system will be found unter UI:Functions
+
         // вводим ноды eEST_UI_TO_SYSTEM; для этой системы событий из раздела UI:Functions
-
         // register as event listener to the event system
+
         // регистрируем как листенер событий
         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 );
-
         // create a new function description for "Foo"
+
         // создаём новое описание функции для "Foo"
         SUIEventDesc fooDesc( "Foo", "Foo", "Call a function named foo" );
         SUIEventDesc fooDesc( "Foo", "Foo", "Call a function named foo" );
-
         // add a parameter description "Arg1" to the function description
+
         // добавляем описание параметра "Arg1" к описанию функции
         fooDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) );
         fooDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) );
-
         // register the function description to the dispatcher
+
         // регистрируем описание функции в диспачере
         m_Dispatcher.RegisterEvent( m_pGameEvents, fooDesc, &CUIFunctions::OnFoo );
         m_Dispatcher.RegisterEvent( m_pGameEvents, fooDesc, &CUIFunctions::OnFoo );
-
         // create another function description for "Bar"
+
         // создаём другое описание функции для "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" ) );
Строка 480: Строка 449:
void CUIFunctions::OnEvent( const SUIEvent& event )
void CUIFunctions::OnEvent( const SUIEvent& event )
{
{
-
     // use the dispatcher to dipatch the event to the correct function
+
     // используем диспачер для диспача события, чтобы откорректировать функцию
     m_Dispatcher.Dispatch( this, event );
     m_Dispatcher.Dispatch( this, event );
}
}
Строка 494: Строка 463:
     }
     }
-
     // do something
+
     // делаем что-нибудь
}
}
Строка 514: Строка 483:
     }
     }
-
     // do something
+
     // делаем что-нибудь
}
}
</source>}}
</source>}}
-
Open *Game.h*, forward declare your class and add a private member to CGame:
+
Откройте '''Game.h''', объявляем свой класс и добавляем частный член в '''CGame''':
{{Код|заголовок=Game.h|блок=<source lang="cpp">#ifndef __GAME_H__
{{Код|заголовок=Game.h|блок=<source lang="cpp">#ifndef __GAME_H__
Строка 545: Строка 514:
</source>}}
</source>}}
-
Open *Game.cpp* init m_pUIFunctions with NULL in the construcor, delete m_pUIFunctions in the deconstructor and create the CUIFunction object at the end of the init function.
+
Откройте '''Game.cpp''' инициализируйте '''m_pUIFunctions''' с '''NULL''' в конструкторе, удалить '''m_pUIFunctions''' в деконструкторе и создайте объект '''CUIFunction''' в конце функции инициализирования.
{{Код|заголовок=Game.cpp|блок=<source lang="cpp">#include "StdAfx.h"
{{Код|заголовок=Game.cpp|блок=<source lang="cpp">#include "StdAfx.h"
Строка 578: Строка 547:
...
...
</source>}}
</source>}}
-
{*}Note:* It is important to create all your classes that uses the UI event system before CompleteInit is called.
+
{{Примечание|Очень важно создать все ваши классы, которые использует система событий UI, прежде, чем вызван '''CompleteInit'''.}}
-
This code will result in two new nodes *UI:Functions:Game:Foo* and *UI:Functions:Game:Bar*.
+
Этот в результате создаст два новых нода '''UI:Functions:Game:Foo''' и '''UI:Functions:Game:Bar'''.
[[Файл:evsys_fct_node.png]]
[[Файл:evsys_fct_node.png]]
-
If the port “send” is triggered, it will call the C+\+ code in UIFunctions.cpp.
+
Если порт '''send''' инициирован, он вызовет код C++ в '''UIFunctions.cpp'''.
-
 
+
-
=== Event Nodes ===
+
-
Event nodes are very similar to Function nodes. They are used to send events from C+\+ to any UI flowgraph.
+
=== Ноды событий ===
-
e.g. you can create a singleton class to call events from everywhere of your code.
+
Ноды событий очень похожи на ноды функций. Они используются для отправки событий из C++ в любой потоковый граф UI.
 +
Например, вы можете создать одноэлементный класс для вызова событий из любой части вашего evenкода.
-
Create a .h file UIGameEvents.h
+
Создайте H-файл '''UIGameEvents.h''':
{{Код|заголовок=UIGameEvents.h|блок=<source lang="cpp">#ifndef __UIGameEvents_H__
{{Код|заголовок=UIGameEvents.h|блок=<source lang="cpp">#ifndef __UIGameEvents_H__
Строка 601: Строка 569:
{
{
public:
public:
-
     // access to instance
+
     // получаем доступ к экземпляру
     static CUIGameEvents* GetInstance()
     static CUIGameEvents* GetInstance()
     {
     {
Строка 608: Строка 576:
     }
     }
-
     // init the game events
+
     // инициализируем игровые события
     void Init();
     void Init();
-
     // events
+
     // события
     enum EUIGameEvents
     enum EUIGameEvents
     {
     {
Строка 630: Строка 598:
</source>}}
</source>}}
-
Create a .cpp file UIGameEvents.cpp
+
Создайте CPP-файл '''UIGameEvents.cpp''':
{{Код|заголовок=UIGameEvents.cpp|блок=<source lang="cpp">#include "StdAfx.h"
{{Код|заголовок=UIGameEvents.cpp|блок=<source lang="cpp">#include "StdAfx.h"
Строка 639: Строка 607:
     if (gEnv->pFlashUI)
     if (gEnv->pFlashUI)
     {
     {
-
         // create a new event system called "Game"
+
         // создаём новую систему событий под названием "Game"
-
         // type is eEST_SYSTEM_TO_UI; nodes for this event system will be found unter UI:Events
+
         // вводим ноды 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 );
-
         // create a new event description for "Foo"
+
         // создаём новое описание события для "Foo"
         SUIEventDesc fooDesc( "Foo", "Foo", "Event named foo" );
         SUIEventDesc fooDesc( "Foo", "Foo", "Event named foo" );
-
         // add a parameter description "Arg1" to the event description
+
         // добавляем описание параметра "Arg1" к описанию события
         fooDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) );
         fooDesc.Params.push_back( SUIParameterDesc( "Arg1", "Arg1", "First Arg" ) );
-
         // register the event to the event system and associate the id with the event enum
+
         // регистрируем событие в системе событий и связываем id с перечислителем события
         m_EventMap[ eUIGE_FooEvent ] = m_pGameEvents->RegisterEvent( fooDesc );
         m_EventMap[ eUIGE_FooEvent ] = m_pGameEvents->RegisterEvent( fooDesc );
-
         // create another event description for "Bar"
+
         // создаём другое описание события для "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" ) );
Строка 660: Строка 628:
void CUIGameEvents::SendEvent( EUIGameEvents event, const SUIArguments& args )
void CUIGameEvents::SendEvent( EUIGameEvents event, const SUIArguments& args )
{
{
-
     // send the event
+
     // отправляем событием
     if (m_pGameEvents)
     if (m_pGameEvents)
     {
     {
Строка 668: Строка 636:
</source>}}
</source>}}
-
Open Game.cpp, include «'''UIGameEvents.h'''» and add to the end of the Init function:
+
Откройте '''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)
Строка 678: Строка 646:
</source>}}
</source>}}
-
The code will create two nodes for the flowgraph:
+
Код создаст два нода для потокового графа:
[[Файл:evsys_evt_node.png]]
[[Файл:evsys_evt_node.png]]
-
Now you can call from everywhere in your code the SendEvent function to trigger e.g. the '''UI:Events:Game:Bar''' Node:
+
Теперь вы можете вызвать из любой части вашего кода функцию '''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-файле со всеми событиями, функциями и переменными, которые должны быть доступны в потоковом графе.

Содержание

Дочерние статьи

Настройка XML для Flash-ассета

Система Flash UI считывает все XML-файлы, которые находятся в Game/Libs/UI/UIElements и создаёт потоковые ноды для контролирования Flash-ассетов.

Откройте существующий XML-файл или создайте новый, чтобы определить новый UIElement.

Основное определение Flash-ассета:

hud.xml
<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, для установки полосы здоровья:

ActionScript
function setHealth(iHealth:Number):void
{
  // установка полосы здоровья
}


Может быть определена в XML так:

hud.xml
<function name="SetHealth" funcname="setHealth">
  <param name="Health" desc="Players current health"/>
</function>


Где name="…" — название функции, отображаемое в потоковом графе, а funcname="…" — название функции в самом ActionScript.

Система автоматически создаст нод, чтобы вызывать эту функцию.

Function node.png

Примечание:
Кроме того, можно определить функции, которые находятся не в корневом пространстве Flash-файла, например:

hud.xml
<function name="SetHealth" funcname="myHealthMc.mysubmc.setHealth">
  <param name="Health" desc="Players current health"/>
</function>

События

Чтобы получить уведомления о каком-либо взаимодействии с пользователем, например, если была нажата кнопка, можно определить события в списке <events>. Чтобы вызвать срабатывание события в коде ActionScript, необходимо вызвать fscommand(«строкаКоманда»). Эти fscommands перехватываются движком.

Например, в функции onPress у кнопки, вы можете вызвать fscommand со строкой «onMyButtonPressed» и несколькими аргументами.

ActionScript
myButton.onPress = function()
{
  var args:Array = new Array();
  args.push(argument1);
  args.push(argument2);
  fscommand("onMyButtonPressed", args);
}


Чтобы перехватить это событие, добавьте тег <event> в список <events>:

hud.xml
<event name="OnButton1" fscommand="onMyButtonPressed">
  <param name="Arg1" desc="Some argument"/>
  <param name="Arg2" desc="Another argument"/>
</event>


Система создаст нод для перехвата этого события.

Event node.png

Переменные, массивы и мувиклипы

Доступ к массиву или переменной также могут быть определены в XML-файле.

Просто добавьте тег <variable> в список <variables>, тег <array> в список <arrays> или тег <movieclip> в список <movieclips>.

hud.xml
<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.

Variable nodes.png

Примечание:
Массивы представляют собой строки разделённые запятой.

Вы также можете получить доступ к определённым мувиклипам через потоковые ноды.

Mc gotoandplay.png

Отображение/скрытие и настройка GFX-файлов

Чтобы отобразить или скрыть Flash-ассет используйте нод UI:Display:Display. Вы можете выбрать элемент в выпадающем списке.

Чтобы настроить поведение и ограничения используйте ноды UI:Display:Config и UI:Display:Constraints соответственно.

Config node.png Constraints node.png

Также можно инициализировать все эти настройки в XML-файле.

hud.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
0=отключено, 1=включено, если включено события мыши будут пересылаться в файле Flash (щелчки и перемещения мыши).

cursor
0=отключено, 1=включено, если включено аппаратный курсор мыши будет видимым пока отображен Flash-элемент.

keyevents
0=отключено, 1=включено, если включено ключи событий будут пересылаться в Flash-элемент.

console_mouse
0=отключено, 1=включено, если включено контроллер будет работать как мышь на консоли (аналоговый стик). Только если включено mouseevents.

console_cursor
0=отключено, 1=включено, если включено аппаратный курсор мыши также будет отображён на консоле. Только если включено cursor.

layer
от 0 до n, определяет, в каком порядке будут отображены элементы (если отображен более чем один Flash-элемент).

alpha
от 0 до 1, альфа фона Flash-элемента.

Ограничения

Доступно три режима размещения ассетов на экране:

"fixed"
В этом режим Flash-ассет отображается в фиксированном положение, определённым значениями top, left, width и height.

"dynamic"
В этом режим ассет выравнивается якорями. Для вертикального выравнивания возможны top, center или bottom, для горизонтального выравнивания возможны left, center или right.

Если scale равно 1, элемент будет максимально масштабирован, не деформируя пропорции. Если scale равно 0, Flash-ассет не будет масштабироваться.

Если max равно 1, то элемент будет максимизирован, так, что 100% экрана будут закрыты (это может привести к тому, что некоторые части элемента выйдут за экран) В противном случае асстер будет подогнан под экран, возможны некоторые незакрытые пространства слева/справа или сверху/снизу.

"fullscreen"
В этом режим окно проекции ассета равно окну проекции рендера. Если scale равно 1 ассет растягивается по размеру всего экрана, в ином случае нет.

Экземпляры элементов

У каждого нода есть порт 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.

Fg fadeElement.png

Потоковые графы UI

Чтобы создать новый потоковый граф для UI, просто откройте Flow Graph и выберите File->New UI Action….

Все действия UI размещены в потоковых графах, а все XML-файлы должны быть сохранены в Game/Libs/UI/UIActions.

FG workspace.png

Примечание:
Все действия UI сохранены отдельно от уровня. Их нужно сохранять через File->Save в меню потокового графа. Убедитесь, что сохраняете каждый раз после изменений!

Все потоковые ноды для UI в списке компонентов UI.

FGfg components.png

Пример

Пример простого потокового графа для показа/скрытия экрана загрузки и определения названия уровня и полосы прогресса.

Example fg.png

Связанный элемент определён в Game/Libs/UI/UIElements/Menus.xml:

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-видео:

Ui action.png

Это действие может быть использовано, например, для воспроизведения видеоролика при входе в Proximity Trigger:

Ui action 2.png

Примечание:
Вы можете управлять любым действием 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:

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:

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:

Game.h
#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 в конце функции инициализирования.

Game.cpp
#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.

Evsys fct node.png

Если порт send инициирован, он вызовет код C++ в UIFunctions.cpp.

Ноды событий

Ноды событий очень похожи на ноды функций. Они используются для отправки событий из C++ в любой потоковый граф UI. Например, вы можете создать одноэлементный класс для вызова событий из любой части вашего evenкода.

Создайте H-файл UIGameEvents.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:

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:

Game.cpp
bool CGame::Init(IGameFramework *pFramework)
{
    ...
    CUIGameEvents::GetInstance()->Init();
}
...


Код создаст два нода для потокового графа:

Evsys evt node.png

Теперь вы можете вызвать из любой части вашего кода функцию 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 );