当前位置:   article > 正文

UE5基础UMG学习记录_ue5 umg

ue5 umg

UMG全称为Unreal Motion Graphics UI Designer,是UE自带的UI设计系统。

新建控件/Widget

最好在工程中新建Widget文件夹,将所有的空间蓝图都放在此文件夹内,方便管理和查找。

新建控件蓝图的方式是右键——用户界面——控件蓝图。

命名最好为UMG_起头,后面跟不同的内容,比如玩家HUD,就是UMG_PlayerHUD。

控件蓝图编辑器

双击打开控件蓝图,进入编辑器,在屏幕主界面/视口周围,分布着不同的面板。

控制板中有自定义控件和UE提供的预制控件,将其拖到层级的其它控件上(或者直接拖进视口)即可生效。

层级相当于布局/Layout,PlayerHUD相当于根节点。

动画和时间轴后续再详细说明。

右侧是细节面板,显示选中的控件的信息。

右上角可以从设计器切换到图表区域,这相当于传统的蓝图图表。

控件蓝图剖析

控件在层级中有固定的父子节点,细节面板中插槽信息会随着父节点不同而变化。

控件的布局

拖动一个Image到画布上,然后再外观-笔刷中选择图像,会发现大小和图片大小不符,因为图片是作为画布的子节点存在,所以会默认跟随插槽中size大小,这时我们可以通过点选插槽中的大小到内容即可。

控件的核心事件

介绍利用图标中的蓝图让数据变动时可以实时更新UI界面。

蓝图中有三个默认事件:

事件预构造:和事件构造类似,只不过是在编辑器中生效。例如编辑设计器视口中的文本,直接用预构造即可,不必运行游戏就能查看更改效果。通常使用在嵌套控件或高级特性时实时更新内容时。

事件构造:在构造或创建控件时,会触发这个事件。

事件Tick:游戏每次刷新逻辑时,或者说游戏中的每一帧都会调用此事件。通常情况下不用,因为每帧执行消耗很大,赛车游戏中计时器往往使用这个,但是血条并不会每一帧变动,所以有些浪费。

我们都不用默认事件,而是自定义,使用类似数据驱动来更新界面,如果玩家血量/弹药等发生变化,我们才更新界面。

新建自定义事件,选中后添加浮点输入,重命名为New Value,代表屏幕上显示的新数值。

将文本细节右小角的是变量打勾编译,这样就可以在图表中看到对应文本的变量。

同样这样设置Ammo文本框,重命名,然后就都可以在图标界面以变量形式显示。

红框的两个变量可以用来访问生命值和弹药的数值。

通过两个自定义函数,将前端界面的生命值和弹药显示更新的前置操作准备完毕。

Append/附加:可以将多个字符串合并成一个字符串。

在屏幕上显示控件

当前我们还没让UI在屏幕上可以显示,当前需要解决这个问题。

因为我们制作的UI是角色相关的,所以我们应该把它和角色绑定,所以我们打开角色蓝图,并在事件图表中加入事件Begin play。

begin play后create widget,class类型选择我们创建的UI控件,然后从return value中选择add to viewport。

大部分情况下都会选择添加到视口,添加到玩家屏幕主要用于分屏显示。

目前UI已经显示在屏幕上了,但是弹药数和生命值固定为100。

所以我们需要断开添加的视口的链接,并从创建控件的Return value连出提升为变量,这样就可以通过这个变量访问控件。接着把变量连到添加到视口。

接下来我们封装一下函数,这个函数目的为和玩家UI通信。

调用我们之前写的两个update自定义事件,但现在只是创建了函数,函数本身却没有被调用,所以我们需要到角色的事件图表,在显示在视图后连上这个函数即可显示默认值。

更新用户界面

目前我们的UI还是静态的,我们需要实时更新数据。

属性绑定可以自动帮助我们更新,但是绑定会每帧更新数据,这对于不会频繁变动的数值来说没有必要。

属性绑定虽然简单,但是性能开销比较大,不建议使用。

在角色蓝图中接受伤害、拾取弹药、开枪的蓝图中加入对应的update事件即可。

但是还有一些问题,比如关卡胜利无变化,或是UI不会识别窗口长宽比变化或缩放,这是因为我们没能正确使用UI布局。

调整用户界面

我们需要使用锚点来调整UI。

将准心锚点选择中心,并将对齐调整为x、y都为0.5(对齐指的是对齐到控件的某位置,范围是0-1,对齐到控件左上角是00,右下角是11)。

这时候只要将准心插槽的位置x和y归零,就可以和锚点位置保持一致了。这样缩放的时候准心就会以锚点为中心。

而生命值就需要将锚点设置在左下,并对齐到x为0&y为1,然后将位置x设置为20,y设置为-20,指向上偏移20,向上偏移20。

接着设置完弹药,UI自适应就完成了。

但是还有一些问题,比如弹药在10变成9的时候,字样会进行缩进,还有没使用等宽字体,我们希望这是固定的。

第一种方法是取消弹药控件“大小到内容”自动调整的勾,而是手动调整插槽下的尺寸。

另一种方式是让组件相互嵌套,两个组件分别表示ammo字样和数字,然后用水平框体作为其父节点进行嵌套。

创建主菜单

文件-新建关卡-空关卡-保存关卡为Map_MainMenu。这就是用作主菜单的关卡,它会在游戏开始前加载。

然后我们需要创建主菜单的控件来显示UI。

我们希望有两个垂直排列的按钮,故选择用垂直框包裹(会直接新建一个垂直框,也可以自行创建垂直框,并手动把按钮拖进去)。

将文本拖到按钮上,让其可以显示内容。然后使用锚点将垂直框居中,按钮看起来比较拥挤。

将按钮水平居中后把填充改为10,填充功能即为添加边距。

然后我们需要一张背景图,拖动图片,并将其锚点设置为右下角的全局。

然后将偏移量全部清零,这时我们发现背景出现了问题,因为它把按钮遮挡了,所以我们需要通过Zorder(深度优先级)管理显示层级,通过将图片Zorder设置为复数,这样会让其变为最底层,就不会覆盖按钮了。

然后选择一张材质,就搞定了。

为主菜单添加逻辑

当我们运行时,会出现两个问题。

首先游戏会显示玩家的HUD,第二点是主菜单并没有显示出来。

这时我们需要打开关卡蓝图,通过获取主菜单控件来显示。

这时候显示角色HUD,是因为角色存在于新建的关卡中,这是默认Pawn,由地图和模式中的游戏模式指定,所以我们需要创建新的地图模式用以覆盖当前地图模式。

新建地图模式,将默认pawn改为none即可。

然后到通过窗口打开世界场景设置,找到game mode进行覆盖(游戏模式重载)即可。

这个时候可以正确显示,但按钮功能还未生效。

当我们创建控件蓝图并添加控件后,图标界面会自动生成默认的变量,每个变量对应几个可选的默认事件。

退出和新游戏使用点击事件可以很简单的赋予功能。

但目前会存在两个问题,第一个是在主界面点击背景后鼠标消失,第二个是new game进入关卡后鼠标默认存在,这是输入方式的问题。

引擎中有三种输入方式:仅UI、仅游戏、游戏和UI。

其中仅游戏是默认的输入模式,所有的输入仅针对游戏启用,游戏逻辑会接收输入而不是UI。

仅UI则只允许UI、UMG元素接受输入信息。

我们希望离开主菜单时,我们要把输入模式设置为仅游戏;但是加载主菜单地图时,我们需要设置成仅UI。而这些需要在关卡蓝图中操作。

如上图所示,我们通过设置输入模式,且set show mouse cursor,就能解决第一个问题。

解决第二个问题可以直接在控件蓝图中点击新游戏后和打开关卡前写蓝图。

问题完美解决。

创建暂停菜单

打开FPS关卡,我们需要添加一个玩家停止事件,让玩家在按下某按键后,能够打开暂停菜单。

所以我们需要打开项目设置,在输入中为暂停按键设置动作映射。

严格来说,暂停按键并不属于关卡,也不属于玩家,我们可以创建新蓝图,但需要通过某个途径访问游戏,游戏中,所有输入都会通过玩家控制器,所以我们可以用Player controller实现暂停事件。

然后我们打开gamemode蓝图,将玩家控制器类改为新建的控制器蓝图。

我们在玩家控制器蓝图中获取暂停输入,创建主菜单控件,但是暂停界面出现时玩家还可以移动。

通过设置输入模式,我们就可以让输入仅会被UI接收,这样角色会暂停了。

但问题在于这种方式没有真正的暂停游戏。

这个也很好解决,在设置输入模式显示鼠标后连接一个set game paused就可以了。

但这又出现了问题,P可以打开暂停界面,但是无法关闭,所以我们要调整输入模式到“游戏和UI”,剩下的问题接下来再解决。

高级UI事件

首先我们要避免每次按P都重新创建控件,通过对创建控件的返回值提升为变量,作为引用。

然后我们要检验引用是否有效,就要使用isValid。

这时按下P仍然不能取消暂停界面,因为set game paused默认会中断输入,我们选中输入操作,并再细节面板中将“暂停时仍执行”打勾即可。

但现在还存在一个问题,就是我们按P取消暂停界面后,游戏仍然没从暂停中恢复。

所以在将引用设置为空后,需要切换inputmode进行一系列设置,如下图所示。

但是这样不断建立并销毁其实对性能有影响,所以一旦涉及到频繁开关的如背包界面,取消显示时让他们从父类移除后不要释放引用对象,单纯让它被隐藏掉就行。

目前还有个问题,就是我们暂停后,玩家HUD依然显示。

所以我们要在角色蓝图中进行设置,我们已经有了PlayerUIRef的引用,所以很方便。

添加两个自定义事件后,我们回到暂停的控制器蓝图。

转化为纯类型就不需要连接执行引脚。

如此就解决了问题。

我们可以开始游戏,可以暂停,但是无法正常通过游戏逻辑结束游戏。

完成游戏反馈循环

我们需要在游戏结束时显示一个UI。

基础逻辑其实没什么变化,所以可以直接复制MainMenu的控件蓝图,稍加修改。

首先将图片材质删掉,把背景Alpha通道透明度改为0.2。

紧接着通过锚点和大小调整game over文本框,因为restart和new game功能一致,所以只需要重命名即可。

然后我们可以通过拷贝和重命名快速设置Main Menu按钮,界面完成了,接下来只需要再图表中写main menu按钮的逻辑就行。

和之前写的开始游戏的逻辑一致,只不过要把打开的关卡换成main menu关卡。

通过工具-在蓝图中寻找,可以找到所有打印字符串的事件,并一个个调整,让其不在左上角显示。

找到Levelend蓝图,我们不需要打印字符串,而是需要显示UI。

打开地图对应的游戏模式蓝图,新建自定义函数handle game over,然后打开Levelend蓝图,补充以下内容调用函数。

然后我们回到Gamemode蓝图,补齐函数逻辑。

现在的问题是仍然显示角色UI,所以我们需要隐藏,直接copy之前在玩家控制器中的toggle事件即可。

这样课程就完全结束了。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/133845
推荐阅读
相关标签
  

闽ICP备14008679号