UI

引擎内包含了一套完整的UI系统,可以用来创建诸如游戏中的HUD、菜单等界面相关图形。

1. UI的制作

MagicCube提供了UI编辑器用于特效资源的制作。详情请参考“UI编辑器“ ui编辑器最终生成表示UI结构的.uix文件,以及表示UI动画的.uianim文件 与ui编辑器配合使用的是合图编辑器。合图编辑器用于将数张小图合成一张大图,并输出配置文件。合图编辑器最终生成.plist文件

2. UI的使用

2.1. 加载UI

用户可通过创建一个UI类型的Actor来使用UI功能。

local UIActor = world:CreateActor(XEUISceneActor.ACTOR_TYPENAME)
UIActor:GetRootComponent():LoadAsset(FileUtils:FilePath(UI_PATH))

2.2. 屏幕适配

创建UIScene时,需要设置设计分辨率和适配模式来适配不同大小的屏幕。 适配方式共有6中,分别为: XUI_EXACTFIT -- 非等比缩放来完全适配
XUI_NOBORDER -- 等比缩放,不留黑边,可能部分UI无法显示
XUI_SHOWALL -- 等比缩放,显示所有UI,可能有黑边
XUI_FIXHEIGHT -- 等比缩放,高度适配,适合横屏
XUI_FIXWIDTH -- 等比缩放,宽度适配,适合竖屏
XUI_CUSTOM -- 自定义适配,屏幕宽高比低于阈值时使用一种方案,高于阈值时使用另外一种方案。

2.3. 控件获取

可通过UIActor获取UIScene,一个UIScene表示一个uix文件,UIScene自身表示当前uix文件的根结点,可通过名称找到下属的任何一个节点。

local UIScene = UIActor:GetScene()
local UIChildNode = IScene:GetChildByNameRecrusive("NodeName")

获取到子节点后,就可以对其进行一系列的操作,如:

UIChildNode:SetVisible(false) --设置隐藏
UIChildNode:SetTouchEnabled(true) -- 设置响应点击事件
UIChildNode:LoadTexture(0, ".../Combin.plist{skill.png}") -- 在Image控件的0号槽位上加载一张图片,该图片来自于合图文件

2.4. 控件对齐

要实现完美的多分辨率适配效果,UI 元素按照设计分辨率中规定的位置呈现是不够的,当屏幕宽度和高度发生变化时,UI 元素要能够智能感知屏幕边界的位置,才能保证出现在屏幕可见范围内,并且分布在合适的位置。可以通过对齐组件来实现这种效果。

  1. 水平方向的对齐策略包括
    • XUI_LEFT(左对齐)
    • XUI_RIGHT(右对齐)
    • XUI_LEFT_RIGHT(左右拉伸对齐)
    • XUI_CENTER(横向居中对齐)
  2. 垂直方向的对齐策略包括
    • XUI_TOP(上对齐)
    • XUI_Bottom(下对齐)
    • XUI_TOP_Bottom(上下拉伸对齐)
    • XUI_CENTER(垂向居中对齐)
  3. 需要贴边的控件对齐策略 通常只需要贴着屏幕边对齐就可以了。 对于UIScene的直接子节点,直接启用对齐并设置相应的对齐策略即可。 对于非UIScene直接子节点的控件,可以在lua代码中设置对齐目标控件 pNode:GetGetAlignment():SetTarget(UIScene) 或者依次设置父控件对齐策略为水平拉伸、垂直拉伸。 系统中默认的对齐目标为父控件,当前编辑器中尚无法直接设置对齐目标,需后续优化添加。
  4. 需要随父节点或屏幕尺寸自动缩放的对齐策略 对齐策略设置为水平拉伸或垂直拉伸,当前控件会自动随对齐目标控件缩放。

在代码中设置:

---这里先取到一个UI控件
local pWidget = XUIWidget:Create()
---获取布局管理器
local pUIAlignment = pWidget:GetAlignment()
---设置有效
pUIAlignment:SetEnabled(true)
---设置对其对象
pUIAlignment:SetTarget(uiScene) --这里可以不是pWidget的父节点
---设置水平对齐策略
pUIAlignment:SetHorizontalEdge(XUIWidgetAlignment.XUI_LEFT)
---设置竖直对齐策略
pUIAlignment:SetVerticalEdge(XUIWidgetAlignment.XUI_TOP)
---设置左右边距
pUIAlignment:SetLeftMargin(fMargin)
pUIAlignment:SetLeftMarginPercent(fPercent)
pUIAlignment:SetRightMargin(fMargin)
pUIAlignment:SetRightMarginPercent(fPercent)
---设置上下边距
pUIAlignment:SetTopMargin(fMargin)
pUIAlignment:SetTopMarginPercent(fPercent)
pUIAlignment:SetBottomMargin(fMargin)
pUIAlignment:SetBottomMarginPercent(fPercent)
---刷新对齐
pUIAlignment:RefreshLayout()

对齐枚举:

  • XUIWidgetAlignment.XUI_NONE 不对齐
  • XUIWidgetAlignment.XUI_LEFT 左对齐
  • XUIWidgetAlignment.XUI_RIGHT 右对齐
  • XUIWidgetAlignment.XUI_LEFT_RIGHT 左右对齐
  • XUIWidgetAlignment.XUI_CENTER 居中对齐
  • XUIWidgetAlignment.XUI_TOP 上对齐
  • XUIWidgetAlignment.XUI_BOTTOM 下对齐
  • XUIWidgetAlignment.XUI_TOP_BOTTOM 上下对齐

2.5. 布局容器

能够自动将子节点按照一定规律排列。

  1. 布局模式:包括水平、垂直、网格状三种模式。
    • 水平布局模式下,不会干涉节点在 y 轴上的位置或高度属性,子节点甚至可以放置在 Layout 节点的约束框高度范围之外。如果需要子节点在 y 轴向上对齐,可以在子节点上添加 Widget 组件,并开启 Top 或 Bottom 的对齐模式。
    • 同理,垂直布局模式下,Layout 组件也不会修改节点在 x 轴的位置或宽度属性。
    • 网格模式可以设置按水平方向排列还是垂直方向排列,子节点x,y坐标均由布局容器进行设置。
  2. 自动对齐 自动对齐属性仅在水平布局或垂直布局时生效,当其中有节点隐藏时,后续节点会自动向前缩进,占据隐藏节点原有位置。

2.6. UI动画

UI动画由美术实现在编辑器中编辑好,在客户端中可以很方便的播放。

local UIAnimIns = UIActor:LoadAnimationAsset(FileUtils:FilePath(UIANIM_PATH)
UIAnimIns = UIActor:GetUIAnimationIns()
UIAnimIns:Apply()
UIAnimIns:GetUIAnimController():SetLoop(false)
UIAnimIns:GetUIAnimController():Play()

2.7. UIAction

UIAction提供通过代码控制UI节点播放动作的功能.

--- XUIMoveTo提供控件在指定时间内移动到指定位置的功能
--- 第一个参数为移动时长 第二个参数是移动到的位置
--- 下边这行代码创建了一个在1秒内移动到(100, 100)的UIAction对象
local pMoveTo = XUIMoveTo:Create(1, XVECTOR2(100, 100))

--- XUIActionEase提供了曲线变化的功能
--- 参数为UIAction
local pActionEase = XUIActionEase:Create(pMoveTo)
--- 设置曲线函数 参数为function<float time> return float 
pActionEase:SetActionTimeFunc(function(time)
    return time
end)

--- XUIScaleTo提供控件在指定时间内缩放到指定大小的功能
--- 第一个参数是缩放时长 第二个参数是缩放的大小
--- 下边这行代码创建了一个1秒内缩放到(0.5, 0.5)倍大小的UIAction对象
local pScaleTo = XUIScaleTo:Create(1, XVECTOR2(0.5, 0.5))

--- XUIColorTo提供了控件在指定时间内变成指定颜色的功能
--- 第一个参数是变色时长 第二个参数是变化的颜色
--- 下边这行代码创建了一个1秒内变化成XCOLORBASE(0.5, 0.5, 0.5, 1)颜色的UIAction对象
local pColorTo = XUIColorTo:Create(1, XCOLORBASE(0.5, 0.5, 0.5, 1))

--- XUIRotateTo提供了控件在指定时间内旋转到指定角度的功能
--- 第一个参数是旋转时长 第二个参数是旋转到的角度
--- 下边这行代码创建了一个1秒内旋转到180度的UIAction对象
local pRotateTo = XUIRotateTo:Create(1, 180)

--- 有时候我们需要进行同步操作 例如在移动的时候进行缩放 变色的时候进行旋转角度
--- 这是我们可以用XUISpawn进行同步操作
--- 参数是一个table, table中存需要进行同步操作的UIAction
local pMoveScale = XUISpawn:Create({pMoveTo, pScaleTo})
local pColorRotate = XUISpawn:Create({pColorTo, pRotateTo})

--- 有时候我们也需要进行顺序操作 例如在移动的同时缩放 结束后进行变色时旋转
--- 这时我们可以用XUISequence进行顺序操作
--- 参数是一个table, table中存需要进行顺序操作的UIAction
local pSequence = XUISequence:Create({pMoveScale, pColorRotate})

--- 我们还支持循环播放动作
--- XUILoopAction提供了循环播放动作的功能
local pLoopAction = XUILoopAction:Create(pSequence)

--- 最后调用XUINode:RunAction播放动作
pNode:RunAction(pLoopAction)

2.8. 事件响应

可以给任何一个控件添加点击事件响应,如下:

local TestButton = UIScene:GetChildByNameRecrusive("TestButton")
TestButton:AddTouchEventListener(function(node, type)
if XUIWidget.XUI_ENDED == type then
    -- 具体的事件响应逻辑
    end
end)

2.9. SubView UI

3D模型在UI上显示,lua代码创建示例如下:

  1. 加载已创建好的subview
    UIChildNode:LoadTexture(0, "subview别名",XUIWidget.XUI_RTT_Tex)
    
  2. lua代码中动态创建
 local subview_preview              = world:FindActor("Subview_for_ui")
 local subview_preview_component = subview_preview:GetRootComponent()
 subview_preview_component:BindSubview("SubView_for_ui",true,true)
 --@init subview param & camera 

 local pSubviewPrimitive = subview_preview_component:GetSubviewAgent():GetSubviewPrimitive(0,1);
 self.subview             = pSubviewPrimitive:GetSubview();
 local pCamera           = self.subview:GetCamera();
 pCamera:SetPos(XVECTOR3(0,0,-4))
 pCamera:SetDirAndUp(XVECTOR3(0,0,1), XVECTOR3(0,1,0));

 pSubviewPrimitive.subViewParamDesc.bEnableSubview = true;

 local clearColorBase = XCOLORBASE(0,0,0,1)
 local clearColor     = clearColorBase:ConvertToRGBAColor()

 subviewParamDesc.clearColor             = clearColor
 subviewParamDesc.bRenderingSubviewForUI = true
 subviewParamDesc.bWriteAlphaWithOne     = false
 subviewParamDesc.bClearColor            = true

 --@add primitive to subview
 local  subviewParamDesc   = self.subview:GetSubviewParamDesc()
 local playeractor         = world:FindActor("player_for_ui")
 playeractor:GetRootComponent():AddToSubview(subviewParamDesc.strRTName,true,false)

 self.subview:ResetupSubview()

2.10. 虚拟列表

  • 仅创建可见范围内数量节点,支持节点复用。
  • 支持惯性动画、回弹效果、跳转、滚动至指定节点。
  • 仅支持横向或纵向滑动,支持横向、纵向、网格状布局。

  • 虚拟列表源数据通过代理方式添加,lua代码创建示例如下:

    local pDelegate = XUIVirtualListViewDelegate();
    --设置获取指定Item的大小的回调
    function pDelegate:GetVirtualListItemSize(view, index)
        return XVECTOR2(x, y);
    end
    --设置获取虚拟列表Item的回调
    function pDelegate:GetVirtualListItem(view,idx)
        local item = view:GetFreeItem();
        --节点复用
        if item == nil then
            item = XUIVirtualListViewItem:Create();
        end
        local pTestNode = item:GetChildByNameRecrusive("Test");
        return item
    end
    --设置获取虚拟列表总Item数量的回调
    function pDelegate:GetVirtualListItemNum(view)
        return #list_num;
    end
    --设置Item点击响应事件回调
    function pDelegate:VirtualListItemTouched(listview,item,pointInItem)
    end

2.11. RichText

RichText提供生成富文本的功能, 可以实现文字和图片一起排版, 其中文字支持描边, 阴影等效果, 图片支持序列帧等效果.

local pRichText = XUIRichText:Create()
---RichText一定要设置ContentSize不为零, 切记! 这个很重要!
pRichText:SetContentSize(XVECTOR2(100, 100))
---创建文字
local pTextElement = XUIRichElementText:Create(0, XCOLORBASE(1,1,1,1), szContent, szFont, nFontSize, nFlag, vOutLineColor, nOutLineSize, vShadowColor, vShodowOffset, nShadowBlurRadius)
---添加到RichText中
pRichText:AddElement(pTextElement)
---创建图片
local pImageElement = XUIRichElementImage:Create(0, vImageColor, pImage);
pRichText:AddElement(pImageElement)

2.12. 合批说明

当前控件中仅使用系统字体的Label控件一定会打断合批的,其他控件只要使用相同材质,均可以合并批次。 使用同一ttf的不同字号、不同颜色、使用描边与否的Label均可进行合批。 UI合批分为两种方式:

  1. 使用Panel
    • Panel内使用同一材质的节点可以跨节点合并批次;
    • 需要说明的是,同一Panel内,如果两个控件使用同一合图文件,且两控件之间存在前后遮挡关系,此时需将两控件间使用同一贴图的不同plist文件(即使用不同材质)
    • 详情请参考“UI编辑器
    • ui-panel-batch
  2. 不使用Panel
    • 此时UI合批的条件是,相邻图元使用同一张贴图或者相邻Label间使用同一ttf字体文件。
    • 不使用Panel模式UI同学制作起来相对耗时,但会对合批提供更精细的控制。
    • ui-batch 整体UI合批流程如下图所示: ui-batch-process UI中可合批的类型当前主要有两种:image和ttf font image 合批条件: ui-image_batch ttf 字体类似。

      2.13. 基于Panel跨UIX渲染流程

      之前以XUIScene级别组织UI场景的渲染,uinode的合批范围也限制在XUIScene中;基于Panel的渲染流程提供了一种比XUIScene更小粒度的ui组织结构,合批范围以及排序规则限制在Panel级别进行; 同时在UIManager中管理和维护场景中Panel集合,并基于Panel实现跨uix的渲染排序。 ui-panel-render
@Copyright © cosmos 2019 all right reserved,powered by Gitbook修订时间: 2021-04-12 18:28:15

results matching ""

    No results matching ""