中ui设置背景图片_玄铁引擎UI实战 - 自动布局篇

从我做玄铁引擎的那一天起,我就不停地听到这样的声音,“没有明星游戏产品的实战案例,你如何证明你的引擎是可靠的”;“某某游戏引擎好厉害啊,用它做的某某游戏月流水过千万”;“没有实际游戏项目支撑的游戏引擎,必定都是坑”。

作为一个技术人,听到这样的声音,一开始我是非常诧异的。渐渐地,听得多了,我也就习惯了。这些声音表面看上去,有一定的“道理”,然细思极恐。这反映了一个令人忧心的现状,负责技术选型的人不具备正面评估一款游戏引擎的能力,而只能根据一些侧面信息来评估。

所以,在开始讲玄铁引擎UI实战之前,我想先科普一些UI有关的基础知识,以便读者可以更好的理解,为什么玄铁引擎UI会设计成这个样子。同时,对于有兴趣讨论的同学,也设立一个基本的讨论标准,避免太过主观而毫无依据的论战,甚至是基于立场的骂战。最后,对于正在或者将要设计一款UI框架的人,也会是一个不错的起点。

Immediate Mode GUI

2002年的秋天,在一次分享会上,一位叫CASEY MURATORI的开发者,借用了游戏引擎里常用的"Immediate Mode Rendering"的概念,第一次提出了“Immediate Mode GUI“,传统的GUI则统一称为“Retained Mode GUI“。2005年,CASEY MURATORI写了一篇博客,详细地介绍了他心中的"Immediate Mode GUI“。本文统一将“Immediate Mode GUI“简称为“IMGUI“,而“Retained Mode GUI“则成为“RMGUI“。

https://caseymuratori.com/blog_0001​caseymuratori.com

IMGUI和RMGUI孰好孰坏,众说纷纭。仁者见仁,智者见智。IMGUI跟RMGUI最大的区别在于,不存储“额外的“,“重复的”状态。比如TextView的Text属性就是一个“额外的”、“重复的”状态。IMGUI不存储Text信息,而是在需要绘制Text的时候,从原始对象中直接获取。这么做的好处是,TextView显示的文本跟原始对象的Text属性永远是一致的。在RMGUI,原始对象的Text变更之后,需要调用TextView::SetText更新TextView的Text属性,否则就产生了不一致。这是RMGUI大部分BUG的根源所在,同时也是一种编程负担。

然而Unity3d告诉我们,IMGUI也有致命的弱点[1],难以进行有效的模块隔离。现有的IMGUI实现采用过程式编程,与RMGUI背道而驰,所有的GUI代码由一个个函数组成,完全抛弃状态,而把所有的状态都放在一个叫做UIContext的对象里,一座新的屎山拔地而起,屹立不倒。IMGUI使用者痛不欲生。

布局系统

现今各种GUI框架使用的布局系统,大致可以分为两种。一种叫Box Layout,一种叫Constraint-based Layout。浏览器和安卓系统使用的布局方案就是典型的Box Layout,而苹果最早引入理念最先进的Constraint-based Layout方案。理论上,Constraint-based Layout是最自由、功能最全面的布局方案,或者说,Constraint-based Layout从理论上统一了布局算法。Box Layout可以说是Constraint-based Layout的子集。

Box Layout

https://www.w3.org/TR/css-box-3/​www.w3.org

Android Layout

https://developer.android.com/guide/topics/ui/declaring-layout​developer.android.com

Apple Constraint-based Layout

Understanding Auto Layout​developer.apple.com
1ab4266b744ac8a7abef2cc4f67e620c.png

玄铁引擎的选择

由于Constraint-based Layout实现过于复杂,使用起来也过度烧脑和繁琐,严重依赖编辑器的完善程度。然而Constraint-based Layout的编辑器开发难度非常大[2],最终玄铁引擎选择了Box Layout方案,使用简单、易于理解、更少的配置代码,而且非常适合实现编辑器。

这样,基本的ui背景知识就讲完了,完整的ui框架所涉及知识非常多,这里就不再深入了。有兴趣的童鞋可以在评论区留言。当然啦,感谢三连,喜欢、收藏、点赞。

打地鼠

回归主体,进入实战。

为了完整地展示引擎的能力,接下来我们要做一个打地鼠游戏。由于本文主要介绍玄铁引擎的UI框架,所以本文会用UI系统来做这个打地鼠游戏[3]

b43afb114015df0fa2df0af47888b79b.png
最终效果图

7b99a2e29059d443a05cfe1ff730c633.png
素材

整个游戏可以分为上、中、下和背景四个部分。最上面是顶栏,中间是游戏核心区域,下面是两个按钮。我们从背景开始。

创建一个名为canvas的BoxWidget根节点,用于预览画布有多大。我们希望canvas铺盖整个可视界面,所以在Layout分组中,我们把Horizontal PolicyVertical Policy都设置为Match Parent,表示匹配父节点大小。在Style分组中,将color设置成#EEEEEE

e4fcf5888e40ccd61d182140861b72fd.png
画布Layout设置

9a588d55892c4c66109d88d6b6760ed7.png
画布Style设置

效果如下图所示,

31720a08b54cdbc4926903cb895e0321.png
画布显示效果

为了适应不同的分辨率,我们希望在不同尺寸的屏幕中,游戏画面永远具中切不缩放,我们创建一个名为artboardBoxWidget,设置如下,

370d7fc8bd50ebc706f9318e458b1db5.png

这次,我们将artboardHorizontal PolicyVertical Policy设置成Fixed,表示固定大小,同时设置WidthHeight属性,这两个属性只会在Fixed时生效。然后,Horizontal AlignmentVertical Alignment均设为Center,表示在父节点中居中。最后,Color属性设置为#CCCCCC,以便跟canvas的颜色区分开。效果如下图所示,

2806486005b5a1dd04e4d216f0731d9b.png
artboard

这时,我们的UI树如下图所示,

8bfbd41663c5e963c1059182820f7182.png
UI树

接下来,我们放背景图。在artboard节点下,我们再创建一个bg1ImageWidget。我们希望背景图覆盖整个artboard,所以Horizontal PolicyVertical Policy均设为Match Parent。在Extension分组中,我们将ImageWidget的Scale Type设置为Fit Inside,表示在保持宽高比的情况下,图片尽可能铺满ImageWidget。Path则设置为背景图片路径。

简单说明一下,为了方便管理资源,玄铁引擎借鉴了Linux文件系统的概念,创建了一个Virtual File System的接口,将不同位置的资源挂载到统一的路径底下。游戏内资源都放在/data/下。

4a1b3f2910868d539c72c3f82858bf19.png
bg1的Extension设置

添加了bg1后的效果如下,

221d18a32cdd8023ae61bc027a5797f2.png
bg1

接着,我们在artboard底下添加游戏核心区域,名为gameBoxWidget。这次我们设置了gameMarginTop属性,表示与父节点的顶部距离。最后给game设置一个带透明度的Color。完整参数如下,

ff52ed9eb0b793ed1c8c213fc5717d30.png
game Layout设置

这时,中间的半透明部分就是我们的游戏核心区域了,

c1171f821e3b04c87b4c7c64f1d5cfe6.png
游戏核心区域

接下来,我们在game节点下,创建一个名为bg2的ImageWidget,用于显示核心部分的背景,效果如下,

46ba409ec3dfc1c95b1949d58d9b6f92.png
添加背景后的核心区域

此时,背景部分我们就全部完成了。本来打算一个篇幅把整个游戏写完,现在看起来篇幅太长了。还是拆分成几个篇幅比较好。

最后,我们把canvas,artboard,game的绘制关闭,因为我们游戏中我们并不需要。只是在创作过程中用于参考而已。在Inspector中找到最顶部的Widget分组,将Draw Enabled的勾勾取消即可。

f76184d7654c8d180ff826abe11772ae.png
禁用绘制

最终效果,

4bccf7a75323e7ed723495dfc0e5b8e6.png
最终效果

最后,我们得到了如下UI树,

f0bf5a442a3607bee50563c573bb1d5d.png
最终UI树

相关文章

独立农场主:玄铁引擎UI框架之自动布局 Part 2​zhuanlan.zhihu.com
82e7963f6e8734db663875e7528837b6.png
独立农场主:玄铁引擎UI框架之自动布局 Part 3​zhuanlan.zhihu.com
d19cb61182cb54b949bc0b0e3a82cf56.png
独立农场主:又双叒叕一款国产商业游戏引擎面世​zhuanlan.zhihu.com
c4f25f24d2b281a20c9af998c78fe8e8.png

=========================================================

欢迎私信、评论交流。感谢喜欢、收藏、点赞。

参考

  1. ^Unity3d的编辑器UI框架属于IMGUI。
  2. ^苹果的Xcode Interface Builder至今没有做对过。
  3. ^正常情况下,游戏性部分不是用UI系统制作的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值