《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

CryEngine:CryENGINE+Game+Programming+with+C++,+C#,+and+Lua 第七章翻译:

7

用户界面

CryEngine 集成了ScaleForm 的GFX文件,允许渲染Adobe公司的FlashBash用户界面,HUDs和动画纹理。将UI元素动态绑定到运行的UI流图方案中。开发人员可以直观的创建和随时展开用户界面。

本章将介绍以下主题:

l  学习CryEngine Scaleform执行过程以及使用Scaleform的益处。

l  创建我们自己的菜单

l  实现一个UI游戏的事件系统

Flash影片剪辑和UI图形

为了向开发者提供创建用户界面的解决方案,CryENGINE集成了Adobe Scaleform GFx,一款用于游戏的实时Flash渲染器引擎。 该系统允许在Adobe Flash中创建用户界面,可以

然后导出以便在发动机中立即使用。

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章它也可以在材料中使用Flash.swf文件,

允许在3D对象上再现Flash影片剪辑

目前在游戏世界。

 

 

 

 

 

创建模块化动态用户界面所涉及的工作大大简化

添加了UI流程图,允许创建和使用流程图系统维护任何FlashUI元素。

 

UI流程系统基于两种类型的概念:元素和动作。 每个元素表示一个Flash文件(.swf或.gfx),而每个动作都是一个表示UI状态的流程图。

Elements

UI元素通过Game / Libs / UI / UIElements /中的XML文件配置代表每个Flash文件。 通过修改UI元素的配置,我们可以改变它接收到的事件和对齐方式,以及在SWF文件中暴露不同的函数和回调实现。

XMLBreakdown

元素的最小值可以在以下代码中看到

<UIElements name="Menus">

<UIElement name="MyMainMenu"mouseevents="1" keyevents="1"

cursor="1"controller_input="1">

<GFx file="Menus_Startmenu.swf"layer="3">

<Constraints>

<Align mode="fullscreen"scale="1"/>

</Constraints>

</GFx>

<functions>

</functions>

<events>

</events>

<Arrays>

</Arrays>

<MovieClips>

</MovieClips>

</UIElement>

</UIElements>

以上的XML代码可以保存为Game / Libs / UI/ UIElements /

MyMainMenu.xml,并将加载名为Menus_Startmenu.swf的Flash文件

Game / Libs / UI /文件夹。

 

一旦创建,我们将能够通过流程图节点选择我们的新UI元素

UI:Display:Config(用于重新配置任何元素,以便例如启用

运行时元素的鼠标事件)。

 

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

现在我们知道它是有效的,让我们把它分解一下:

<UIElementsname="Menus">

第一个元素定义了文件的开始,并确定了些类别元素应该被放置。

<UIElementname="MyMainMenu" mouseevents="1" keyevents="1" cursor="1"controller_input="1">

UIElement XML元素用于决定初始配置,包括默认名称,并确定默认情况下应接收哪些事件。

如前所述,每个元素可以通过一组属性进行配置,允许开发者监听不同种类型的事件。

属性名称

描述

name

定义元素(String)的名称

mouseevents

确定鼠标事件是否发送到Flash文件(0/1)

cursor

确定是否显示光标该元素是可见的(0/1)

keyevents

确定是否发送关键事件Flash文件(0/1

console_mouse

确定鼠标是否应该作为控制台硬件上的光标(0/1)

console_cursor

确定是否显示光标当元素在控制台硬件运行时可见(0/1)

layer

在多个元素的情况下显示时定义元素的顺序

alpha

设置元素的背景alpha透明是否有效(0-1),允许游戏使用透明度,例如,在您的主要背后具有游戏中的级别菜单

 

注意我们之前提到的属性可以通过UI:Display:Config节点在具体的时间被中调整(有些拗口,或许翻译的不对:Notethat the previously mentioned properties can be tweaked in real

time by using the UI:Display:Config node.)

 

 

 

 

<GFxfile="Menus_Startmenu.swf" layer="3">

GFx元素决定了那个flash文件将被该元素加载,它可以加载多个GFX文件到不同的层中。

这允许在运行时选择要使用的元素层,例如通过UI上的输入:UI:Display:Config节点,显示在上一屏幕截图中。

<Constraints>

<Alignmode="fullscreen" scale="1"/>

</Constraints>

限制条件允许配置GFx元素在屏幕上的显示方式,使开发人员能够在不同之分辨率下调整元素的性能。

目前有三种模式如下:

模式名称

描述

属性

Fixed

在固定模式下,开发人员可以使用四个属性设置像素距离从顶部和左上角,以及设置所需分辨率。

top, left, width, height

dynamic

在动态模式下,元素对齐在锚点上,允许水平和

垂直对齐。

可以将halign设置为left,center或right,而valign可以设置为top,center, or bottom.

如果比例设置为1,则元素将为缩放到屏幕分辨率

保持长宽比。

如果max设置为1,则元素将为最大化以确保100%

的屏幕覆盖。

halign, valign, scale, max

fullscreen

当在此模式下**时,元素视口将完全一样

渲染视口。

如果比例设置为1,则元素将为拉伸到屏幕分辨率。

Scale

 

Actions

UI动作是UI流程图实现的核心。 每个动作都是由流程图表示,并定义UI状态。例如,每个屏幕在一个主菜单将使用单独的操作来处理。

所有可用的UI操作都可以在流程编辑器的Flow Graphs工具箱中看到:

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

要创建一个新的UI操作,请导航到File | 新的UI操作,并指定名称

在新打开的另存为对话框中的新操作

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

通过使用UI:Action:Control节点并在UIAction输入端口指定名称来启动操作,然后**启动输入。

 

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

一旦开始,具有指定名称的UI图形将被**,假定它包含一个UI:Action:Start节点如图所示

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

然后,该图可以通过监听StartAction输出来初始化所请求的UI端口。一旦操作完成,它应该调用UI:Action:End如图所示:

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

就是这样, UI图形作被作为为流图的XML文件保存在Game / Libs / UI /UIActions /。 初始UI操作称为Sys_StateControl,并将始终为**。 状态控制器图负责加载和启用基于系统事件的菜单,如:加载关卡。

系统状态控制动作(Sys_StateControl.xml)始终处于活动状态用于启动初始动作,例如,当引擎启动时,显示主菜单界面

 

Creatinga main menu

现在我们对UI流程图的实现有一个基本的了解开始创建我们自己的主菜单。

Creatingmenu elements

我们需要做的第一件事就是创建我们的UI元素定义,用于引擎加载SWF文件。

为此,请在Game / Libs / UI /UIElements / named中创建一个新的XML文档

MainMenuSample.xml。 我们的菜单所需的最低限度的代码可以在这里看到以下代码:

<UIElementsname="Menus">

<UIElementname="MainMenuSample" mouseevents="1"keyevents="1"

cursor="1"controller_input="1">

<GFxfile="MainMenuSample.swf" layer="3">

<Constraints>

<Alignmode="dynamic" halign="left" valign="top"scale="1"

max="1"/>

</Constraints>

</GFx>

</UIElement>

</UIElements>

使用以前的代码,引擎将知道在哪里加载我们的SWF文件,以及如何在屏幕上对齐它。

 

可以使用GFxExport.exe重新导出SWF文件(通常

存在于<root> / Tools /目录中)以提高

引擎使用效率使用。 这通常在发布游戏之前完成。)

 

 

 

Exposing ActionScript assets

继续,我们需要公开我们在Flash中定义的功能和事件源文件,以允许引擎调用和接收这些事件。

当暴露函数和事件时,我们创建可以简化的流程图节点由任何流程图使用。

创建后,可以通过导航到UI | Functions来访问节点,如下图所示:

事件可以在UI | Events中找到.

也可以有效地在C++中创建UI动作和元素,使用户界面能够从本机发送和获取事件码。我们将在创建UI游戏事件系统中完成此操作。

 

 

 

 

 

 

 

函数(Functions)

要导出一个方法,我们需要在UIElement中添加一个新的<functions>部分

定义如下代码所示:

<functions>

<functionname="SetupScreen" funcname="setupScreen" desc="Sets

upscreen, clearing previous movieclips and configuring

settings">

<paramname="buttonX" desc="Initial x pos of buttons"

type="int"/>

<paramname="buttonY" desc="Initial y pos of buttons"

type="int"/>

<paramname="buttonDividerSize" desc="Size of the space

betweenbuttons" type="int" />

</function>

<functionname="AddBigButton" funcname="addBigButton" desc="Adds

aprimary button to the screen">

<paramname="id" desc="Button Id, sent with the onBigButton

event"type="string" />

<paramname="title" desc="Button text" type="string"/>

</function>

</functions>

 

使用以前的代码,引擎将创建两个可以用来调用的节点

我们的UI Graphs中的setupScreen和addBigButtonActionScript方法。

功能总是放在同一流程图中:

UI:Functions:ElementName:FunctionName

 《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

 

 

 

当上一屏幕截图中显示的节点上的输出端口触发后,将使用指定的参数调用ActionScript方法

 

instanceID输入端口确定哪个元素实例调用该功能。 如果该值设置为-1(默认),它将为在所有实例上调用,否则如果设置为-2,它将被调用所有初始化的实例。

 

 

 

 

 

 

事件(Events)

通过使用<events>标签,以类似于函数的方式设置事件显示:

<events>

<eventname="OnBigButton" fscommand="onBigButton"

desc="Triggeredwhen a big button is pressed">

<paramname="id" desc="Id of the button" type="string"/>

</event>

</events>

 

以上的代码将导致引擎使OnBigButton节点可用,当Flash文件调用onBigButton fscommand时,并传入关联的按钮ID:

 《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

 

从Flash中回调fscommand是比较容易. 以下代码触发了onBigButton事件,并传递buttonID参数。

fscommand("onBigButton",buttonId);

 

与函数类似,事件也可以在下面找到: UI:Events:ElementName:EventName.

 

 

 

 

变量(Variables)

也可以定义对Flash源文件中存在的变量的访问权限。 这允许通过获取和设置变量的值

使用UI:Variable:Var节点。

首先,在元素定义的<variables>块中定义你的数组:

<variables>

<variablename="MyTextField"

varname="_root.m_myTextField.text"/>

</variables>

重新启动编辑器后,放置一个新的UI:Variable:Var节点并浏览新变量如下图所示:

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

现在,我们可以通过流图随时set和get变量的值:

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

数组(Arrays)

在上一节中,我们在运行时设置了一个Flash变量的值。 这也是通过使用UI:Variable:Array节点可能的数组。

首先,将数组暴露在元素的<array>块中,如图所示:

<arrays>

<array name="MyArray"varname="_root.m_myArray"/>

</arrays>

然后,只需重新启动你的数组,并重复上一个小结的操作,但是节点变成:UI:Variable:Array。要通过UI图形创建一个新数组,请使用UI:Util:ToArray节点:

 《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

将MovieClip实例暴露给流程图

以与变量相似的方式,也可以通过UI图形直接访问到MovieClip。这允许有可能去特定的框架,

更改属性等.

 

所有的节点可以通过UI |MovieClip进行交互,如下图所示:

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

首先,在元素定义中添加或者编辑<movieclips>块,如下所示:

<movieclips>

<movieclip name="MyMovieClip"

instancename="_root.m_myMovieclip"/>

</movieclips>

 

这将使流程图可以访问你的m_myMovieClip变量,显示Flash文件中的动画剪辑。

编辑器重新启动后,我们可以使用UI:MovieClip:GotoAndPlay节点直接跳到不同的帧

指定剪辑,如下面的截图所示:

 《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

创建UI操作

我们已经配置了主菜单元素,现在改创建UI操作了,它将会在启动程序中出现菜单。

创建状态控制图

打开Sandbox的flowgraph 编辑器,通过File | New UI Action,创建新的UI操作,调用Sys_StateControl操作,在触发初始化菜单和处理重要的系统事件,这将成为主要的UI操作。

一旦操作被创建,我们将使用三类系统消息:

l  OnSystemStarted

l  OnLoadingError

l  OnUnloadComplete

有了这些,当主菜单出现时,我们的事件将会有意义,我们将使用UI:Action:Control 节点,我们稍后将使用它**主菜单的UI操作。

 《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

创建主菜单操作

完成以上操作,我们另外创建一个MainMenu的UI操作,打开该操作,放置一个UI:Action:Start 节点。当我们先前创建的UI:Action:Control 被执行时,StartAction的输出端口会自动**,现在我们可以将Start节点关联到UI:Display:Display and UI:Display:Config节点,以便初始化主菜单,确保用户可以看到它。

当前启动程序后,flash文件将会被显示,现在,需要在flowgraph中添加一些配置

添加按钮

现在我们的主菜单文件已初始化,我们需要添加一些ActionScript代码到Flash文件,在UI流图中,以便允许动态产生和处理按钮。

本部分假设您有一个MovieClip,您可以在运行时实例化。

在我们的示例中,我们将使用一个名为BigButton的自定义按钮。

本节还假设您有两个ActionScript函数:SetupScreen和AddBigButton

 

SetupScreen应该配置场景的默认设置并删除所有以前产生的对象。 在我们的例子中,我们需要使用的按钮当我们调用SetupScreen时,AddBigButton被删除

AddBigButton应该只是一个产生一个预先创建的按钮的函数

实例如图所示:

《CryENGINE+Game+Programming+with+C++,+C#,+and+Lua》第七章

var button =_root.attachMovie("BigButton", "BigButton" +

m_buttons.length,_root.getNextHighestDepth());

 

 

https://www.bilibili.com/video/av6465791/index_3.html#page=3