斯坦福 UE4 C++ ActionRoguelike游戏实例教程 08.创建主HUD & 自定义作弊指令
斯坦福课程 UE4 C++ ActionRoguelike游戏实例教程 0.绪论
概述
本篇文章对应课程Lecture 14 ,56-58节。本篇文章将会教你将之前创建的各种UMG控件统合到一个主控件上。此外,还会教你如何在C++中创建自定义作弊指令,并在游戏中使用控制台执行它。
目录
- 创建主HUD
- 使用GameMode生成玩家
- 自定义控制台命令
创建主HUD
在之前的课程中,我们创建了各种各样的UMG控件,比如屏幕中心的准心,玩家的血条等,并通过分别调用CreateWidget的方式创建它们,最后添加到视口中。这样做有一个问题,每一个控件都是单独设计并添加的,当控件多起来后,我们很难管理它们之间的位置关系,而且分散创建的方式为程序的维护也带来了许多不便。为了解决这个问题,我们这里创建一个主控件,将之前创建的空间作为子控件统合在一起,并简单设置它们之间的位置。具体怎么操作,让我们边做边说。
顺带一提,在UE中HUD类和UMG是效果类似但是实际上几乎完全不一样的两个东西。通常HUD类继承自Actor,UMG控件继承自UObject,并且有着独特的设计方式。这里标题虽然写着创建HUD,是因为UMG控件所制作的UI,在概念上还是属于HUD(抬头显示),仅仅是为了和课程一致,实际上还是创建UMG控件,请读者不要在这里混淆。
创建Main_HUD
和之前创建控件的方式一样,我们创建一个Main_HUD,作为玩家HUD的容器。

在控制板中可以搜索到我们以前创建的控件,这里我们将玩家血条PlayerHealth_Widget和准星Crosshair_Widget空间添加到画布面板中。

为了将准星居中,我们设置准星空间的锚点为右下角最后一个。顺带一提,在页面布局中,锚点通常是用来控制与父级组件的相对位置关系的,读者可以移动锚点,尝试缩放界面来体会它的作用。

修改准星锚点的大小如图所示:

注意到,我们玩家血条控件拥有自己的画布面板。如果玩家血条是直接被添加到玩家视口中时,画布面板可以为其中的血条组件提供一个很好的容身之所(相对位置、大小尺寸),但是在这里,我们希望玩家血条的位置和大小由主HUD来控制。所以我们需要将玩家血条的画布面板删除掉。操作如图所示,进入玩家血条控件的设计界面,将画布面板替换为子项:

可以看到原本画布面板的内容占据了整个界面。不要慌,这只是预览效果,玩家血条的显示效果最后还是得由父组件来决定。这里为了优化我们的设计体验,我们可以点击右上角,设置屏幕上所需或者自定义来自定义预览效果。
当然,到了这一步,我们之前创建控件添加到视口的操作就可以作废了,现在去运行游戏,你会被血条糊一脸。当然,这不是设计阶段该考虑的事情。


现在我们可以把之前创建血条和准星控件的相关蓝图(代码)删除掉了,我们现在只需要留一个Main HUD控件即可。

创建Credit_Widget
接下来我们可以丰富一下主HUD的显示。
创建一个Credit_Widget,用于显示玩家的积分等信息。我们不需要画布面板,就像之前一样,将其替换为子项。
最终布局如图所示:

创建GameModeInfo_Widget
我还想在HUD中看到当前游戏的进行时间。操作和上面一样
创建一个GameModeInfo_Widget:

为了做到实时获取游戏时间,我们需要为文本创建一个函数绑定,将其命名为GetGameTimeText,他将会每帧调用这个函数。

这里使用蓝图的方式创建函数。注意到我们是通过游戏状态来获取服务器场景时间。因为如果我们是多人游戏,我们希望中途加入游戏时得到的是总的游戏时间,而不是从0开始。在进行多人游戏时,UE会不断地同步GameState,从中获取服务器场景时间十分合适。

将上述两个控件加入到主HUD中。如图所示,这是我们目前的HUD结构,为了获得更好的布局效果,我使用了垂直框将血条和Credit控件捆绑在了一起。除非是很简单的HUD,否则都不推荐使用手动调整的方式来设置页面布局:

调整GameModeInfo控件如图所示,注意我们HUD里的控件都勾选了大小到内容:

调整垂直框为如图所示。有的同学选择了大小到内容后,血条会变得很短一条,这个问题可以通过调整血条材质图片的大小来解决。

最后是进入游戏后的效果:

使用GameMode生成玩家
接下来是一些比较零散的知识点。如果你看过谌嘉诚大佬的UE4入门视频,他会教你通过设置场景中角色的自动控制玩家来让你在进入游戏的时候能自动控制一个角色。如下图所示,我们可以选择场景中已经存在的角色,通过选择自动控制玩家中的玩家0来自动控制角色:

然而在很多场景中,玩家角色并不是一开始就在场景里的,我们需要使用下面的方法来生成角色:
- 设置玩家出生点。玩家的出生点也是一个可以放置在场景中的Actor,我们可以在左侧搜索获得。

- 在世界场景设置中,选择一个游戏模式,并且在下方的默认Pawn类中选择我们要生成的角色类。

通过以上两个步骤,UE就会根据GameMode里预设的默认Pawn类,在场景中的玩家出生点(如果有多个的话)中随机选取一个出生点,生成指定的Pawn类,并让玩家控制他。
我们同样可以在项目设置中设置整个游戏的默认游戏模式,这样在进入游戏时,如果世界场景设置的游戏模式为None时,就会加载默认游戏模式。不过,世界场景设置中设置的游戏模式优先级还是最高的,如果世界场景设置里有对游戏模式进行设置,就会执行世界场景设置里的游戏模式。

自定义控制台命令
就拿大家最熟悉的MineCraft来举例,大家都知道MC这款游戏只要开启作弊模式,玩家就可以在下方的控制台(聊天框)输入各种各样的作弊指令进行作弊,例如获取物品、飞行等等。UE同样为游戏开发者提供了自定义控制台命令的方式,游戏开发者可以在C++里自定义控制台命令,并在游戏运行时打开控制台输入相关指令。
这里为大家演示了如何在C++中自定义作弊指令,值得一提的是,这个方式只有将函数添加到玩家控制的角色类上或者GameMode类或者CheatManager类上才能生效。如果是其他普通的Actor类就不会生效。也许是必须由玩家控制器类能访问到的对象才能进行自定义指令。
自愈指令
在玩家角色类中添加一个函数,这个函数必须用UFUNCTION修饰,并在里面加上Exec修饰词,这才能表明这个函数要在控制台上也能够访问。
这里的控制台命令将会执行回血的操作。具体用法为进入游戏,点击·(tab键上面的那个键), 以函数名为指令,后面的参数作为函数参数,回车即可执行函数。
//MyCharactor.h
UFUNCTION(Exec)
void HealSelf(float Amount = 100);
//.cpp
void AMyCharacter::HealSelf(float Amount)
{
AttributeComponent->ApplyHealthChanges(this, Amount);
}

杀死所有AI指令
同样的道理,在GameModeBase类里我们定义了一个杀死所有AI的指令,方法同上。
//ASurGameModeBase.h
UFUNCTION(Exec)
void KillAll();
//ASurGameModeBase.cpp
void ASurGameModeBase::KillAll()
{
for(TActorIterator<ASurAiCharacter> It(GetWorld()); It; ++It)
{
ASurAiCharacter* Bot = *It;
USurAttributeComponent* AttributeComp = USurAttributeComponent::GetAttributes(Bot);
if(AttributeComp && AttributeComp->IsAlive())
{
AttributeComp->ApplyHealthChanges(this, AttributeComp->GetMaxHealth() * -1);
}
}
}

总结
在本篇文章里,我们更加深入了解了UMG控件的使用,将创建的大大小小的控件都塞进了一个主控件中。此外,还简单了解了一下由GameMode控制生成的玩家角色。最后,学习了在C++中自定义控制台指令的办法。
斯坦福 UE4 C++ ActionRoguelike游戏实例教程 08.创建主HUD & 自定义作弊指令的更多相关文章
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程08:虚拟键盘实现》--本系列完结
8.虚拟键盘实现 概述: 硬键盘就是物理键盘,平时敲的那种.软键盘是虚拟的键盘,不是在键盘上,而是在"屏幕"上.虚拟按键就是虚拟键盘的一部分,根据功能需求,提供部分按键效果的UI可 ...
- Cocos2d-x3.0游戏实例《不要救我》第十篇(结束)——使用Json配置数据类型的怪物
如今我们有2种类型的怪物,并且创建的时候是写死在代码里的,这是要作死的节奏~ 所以.必须可配置.不然会累死人的. ; i < size; ++i) { int id = root[i][&quo ...
- Cocos2d-x3.0游戏实例之《别救我》第八篇——TiledMap实现关卡编辑器
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/musicvs/article/details/25368273 好吧.我真心全然搞不懂.我如今仅仅只 ...
- Silverlight,Windows 8应用开发实例教程系列汇总
Kevin Fan分享开发经验,记录开发点滴 Silverlight,Windows 8应用开发实例教程系列汇总 2012-06-18 01:05 by jv9, 2145 阅读, 3 评论, 收藏, ...
- 《Genesis-3D开源游戏引擎完整实例教程-2D射击游戏篇:简介及目录》(附上完整工程文件)
G-3D引擎2D射击类游戏制作教程 游戏类型: 打飞机游戏属于射击类游戏中的一种,可以划分为卷轴射击类游戏. 视觉表现类型为:2D 框架简介: Genesis-3D引擎不仅为开发者提供一个3D游戏制作 ...
- Python导出Excel为Lua/Json/Xml实例教程(一):初识Python
Python导出Excel为Lua/Json/Xml实例教程(一):初识Python 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出 ...
- Web 开发中应用 HTML5 技术的10个实例教程
HTML5 作为下一代网站开发技术,无论你是一个 Web 开发人员或者想探索新的平台的游戏开发者,都值得去研究.借助尖端功能,技术和 API,HTML5 允许你创建响应性.创新性.互动性以及令人惊叹的 ...
- 值得 Web 开发人员收藏的20个 HTML5 实例教程
当开始学习如何创建 Web 应用程序或网站的时候,最流行的建议之一就是阅读教程,并付诸实践.也有大量的 Web 开发的书,但光有理论没有实际行动是无用的.现在由于网络的发展,我们有很多的工具可以用于创 ...
- 对《[Unity官方实例教程 秘密行动] Unity官方教程《秘密行动》(十二) 角色移动》的一些笔记和个人补充,解决角色在地形上移动时穿透问题。
这里素材全是网上找的. 教程看这里: [Unity官方实例教程 秘密行动] Unity官方教程<秘密行动>(九) 角色初始设定 一.模型设置: 1.首先设置模型的动作无限循环. 不设置的话 ...
- Cocos2d-x3.0游戏实例《不要救我》第一章——前言
我们可以学习? 这是一个非常easy游戏.但更多的东西用(对于初学者).至少,对于它的一个例子,有点多. 笨木头花心贡献.啥?花心?不呢.是用心~ 转载请注明,原文地址:http://www.benm ...
随机推荐
- 【Flutter】如何优美地实现一个悬浮NavigationBar
[Flutter]如何优美地实现一个悬浮NavigationBar 最近写代码的时候遇到了一个如下的需求: 整体来说,底部的条是一个浮动的悬浮窗,有如下的三个按钮: 点击左边的要进入"主页& ...
- Gossip in Hyperledger Fabric
1. Gossip协议基础 1.1 什么是分布式系统 分布式系统(Distributed System)是由多台计算机或计算节点组成的计算机系统,这些计算节点通过网络连接在一起,并协同工作以完成共同的 ...
- Kubernetes集群管理面板的安装及使用
Kubernetes集群管理面板的安装及使用 1.前言 若海的腾讯云Lighthouse组建跨地域Kubernetes集群,让我成功体验到了Kubernetes集群诸多优点,但是非技术出生的我,长时间 ...
- AI图形算法的应用之一:通过图片模板对比发现油田漏油
最近研究了一下OPENCV的图像算法,开发了一个小应用. 可以通过图像和模板进行对比,发现油田或其他作业区漏油. 直接上效果,模板如下 自己模拟了一个漏油的现场图片,如下 通过图形化算法,找到漏油点, ...
- 【虹科干货】Redis 开发者需要了解的缓存驱逐策略
在你搭建并配置了一个Redis数据库之后,Redis成功地提升了应用程序性能.然而这里有一个潜在问题,随着缓存数据的快速增加和内存占用率的逐渐上升,你很快会发现Redis缓存容量即将达到硬件存储容量上 ...
- Redis 6 学习笔记 2 —— 简单了解订阅和发布(Pub/Sub),JDK17环境下用Jedis 4.3.1连接Redis并模拟验证码发送
REDIS pubsub -- Redis中国用户组(CRUG) 什么是发布和订阅 Redis发布订阅是一种通信模式:发送者(Pub)发送消息,订阅者(Sub)接收消息.Redis客户端可以订阅任意数 ...
- 高精度减法(C语言实现)
高精度减法(C语言实现) 介绍 众所周知,整数在C和C++中以int ,long,long long三种不同大小的数据存储,数据大小最大可达2^64,但是在实际使用中,我们仍不可避免的会遇到爆long ...
- IT运营与DevOps:有何不同?
IT 运营和 DevOps 满足许多现代企业密切相关的需求.然而,尽管这两种角色之间有许多相似之处,但也有重要的区别,将 IT 运营与 DevOps 混为一谈是错误的. 本文通过解释每种类型的角色是做 ...
- mysql 代码适配 postgresql 适配改写,优化案例(行转列 + 标量子查询改写)
最近在适配个MySQL应用的项目,各种SQL改成PG兼容的语法真的是脑壳痛,今天遇到个有意思的案例. 原 MySQL SQL语句: SELECT DISTINCT l.MALL_NAME '项目', ...
- 【pwn】整数溢出
这是ctfshow上面的一道题 这边v1和v2定义时都是int,有符号整数,想让v1-v2=9,可以考虑负数,但是这个函数过滤了负号 if ( strchr(s, 45) ) return ...