斯坦福课程 UE4 C++ ActionRoguelike游戏实例教程 0.绪论

概述

本篇文章对应Lecture 17 - GameplayTags, 70节。本文将会结合前几节课使用的能力系统和GameplayTag系统,实现一个防守反击的技能,按下R键,即可在1秒钟内反弹魔法子弹的攻击。

如果不清楚能力系统可以查看之前写的文章https://www.cnblogs.com/Qiu-Bai/p/17326408.html

防守反击技能

如果玩过守望先锋,想必会对源氏的E技能“闪”印象深刻,该技能在两秒钟内反弹源氏面前的所有投射类物体,无论是子弹还是各种技能。

源氏的E技能 图源百度

而这篇文章,将会实现一个简易版的防守反击技能,在你按下释放键后,将会给你一个持续一段时间的“招架”状态,此时会反弹所有打向你的魔法子弹。

我们将使用GamePlayTag来实现状态的赋予。原理很简单,当我们按下技能键后,会给角色上一个“招架(parring)”的Tag,当子弹打到角色身上时,会检查角色身上的Tag,如果有parry的Tag,那么就将其速度和方向取反。具体怎么实现,我们边做边说。


由于是子弹检测角色身上的Tag,所以检测Tag部分的逻辑我们写在子弹的类中。

如下所示,我们在头文件中定义了要检测的Tag类型 ParryTag,并修改了OnOverlapBegin里面的部分逻辑,添加了了检测目标角色身上的Tag,如果目标身上有指定的ParryTag,就将子弹的速度取反,并重新设置Instigator。

//SurMagicProjectile.h
protected:
UPROPERTY(EditAnywhere, Category = "Tags")
FGameplayTag ParryTag; //SurMagicProjectile.cpp
void ASurMagicProjectile::OnOverlapBegin(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if(OtherActor && OtherActor != GetInstigator())
{
// 被魔法球攻击的Actor如果有ParryTag,那么它将反弹魔法球
USurActionComponent* ActionComp = Cast<USurActionComponent>(OtherActor->GetComponentByClass(USurActionComponent::StaticClass()));
if (ActionComp && ActionComp->ActiveGameplayTags.HasTag(ParryTag))
{
MoveComp->Velocity = -MoveComp->Velocity; SetInstigator(Cast<APawn>(OtherActor));// 反弹魔法球之后,魔法球的Instigator改为反弹者
return;
}
...
}
}

代码就修改到这边,后面的步骤并不复杂,主要用蓝图实现。

首先添加Parrying的Tag。

添加Status.Parrying

值得一提的是,课程里提到为Tag起名并做好分类是非常重要的事情。这里为Parrying添加了Status的前缀,推测其目的是为之后的角色状态相关设计打下基础。熟练的游戏设计者考虑问题总是先人一步,但是作为新手,如果缺乏经验的话,在一开始确实很难想到这么多。

然后是创建招架的技能。继承自前几节课创建的SurAction,将其命名为Action_Parry。将其细节设置如下:

将新能力起名为Parry

重载StartAction事件,在这个技能持续期间,会为角色的ActionComponent组件添加上Parrying标签(父类StartAction),持续一秒。

Action_Parry的事件图表

注意要将SurAction的StopAction设置为BluprintCallable,否则在蓝图中是无法直接调用的。

延续上面的话题,在项目越来越大的时候,我们应该考虑使用GameplayTag来代替这里使用的FName,因为为能力命名实际上也是一门不小的学问,我们在实现越来越多的Action时,也许会遗忘某个Action的ActionName,或者会疑惑“当时我为什么要这么命名?”,又或者不小心打错了某个字符,在后期开发了几百上千个Action后,为每个Action命名也是相当繁琐且困难的。

但是,如果用标签的组合来标识每一个Action的话,也许在开发新Action的时候就会省力很多,毕竟我们可以自由选择标签组合来赋予Action特征和属性,也不用不厌其烦地为Action起名了。当然,这一切的前提是你有一套足够合理的标签系统,这又是一门大学问了。现在我们的项目只是为了练手和入门,就先不考虑这些了。


技能创建好后,为技能绑定按键。这里将其设置为R键。

项目设置->引擎->输入->操作映射

在我们的角色类中,为该键绑定事件,和之前一样,直接调用ActionComponent的StartActionByName。注意Action Name要和技能里的Fname一样。

绑定按键事件

为角色添加默认技能:

添加默认技能

对了,前面还为子弹添加了一个ParryTag成员。别忘了为子弹设置好要检测的标签。

设置要检测的标签

进入游戏看看效果,当AI小兵向我们发射子弹的时候,我眼疾手快,按下R键释放格挡反击技能。左上角提示,现在角色带有了Parry标签,子弹命中我的时候,检测到Parry标签,将自己的速度取反,并重新设置Instigator,相当于这个子弹是被我发射出来的。最终,小兵被反弹的子弹击杀。

最后玩点花的,我们可以给AI小兵也加上ActionComponent,为其添加一个parry标签,这样子弹打在小兵身上时就会反弹回来,如果此时我们角色身上也有parry标签,最后双方互相反弹,跟打乒乓球一样,十分有趣。

期间我一直在狂按R键

添加AI角色伤害数字UI

因为这部分东西很少,都是以前做过的内容,出于记录的目的,姑且放在本篇文章中。

在Ai角色蓝图中绑定OnHealthChanged事件,创建DamagePopup_Widget控件

这里我为DamagePopup_Widget的伤害数字增加了简单的上浮动画

为DamagePopup_Widget添加播放动画的蓝图节点

总结

本篇文章结合了前面实现过的Action System和UE中的GameplayTag系统,实现了可以反弹子弹的格挡反击技能。

注意到利用GamePlayTag实现这些效果并没有与特定的Actor或者组件相关联,我们可以将游戏标签用在游戏项目里的各种地方上,大大降低了程序的耦合性,这是游戏标签非常棒的特点之一。

通过这几节课的学习,我们已经基本掌握了GameplayTag的基本用法,除此以外,它还有大量的用法尚待发掘,相信在学完了这几节课后,大家对游戏的开发会更加得心应手。

斯坦福 UE4 C++ ActionRoguelike游戏实例教程 14. 使用GameplayTag实现防守反击技能的更多相关文章

  1. Cocos2d-x3.0游戏实例《不要救我》第十篇(结束)——使用Json配置数据类型的怪物

    如今我们有2种类型的怪物,并且创建的时候是写死在代码里的,这是要作死的节奏~ 所以.必须可配置.不然会累死人的. ; i < size; ++i) { int id = root[i][&quo ...

  2. Cocos2d-x3.0游戏实例之《别救我》第八篇——TiledMap实现关卡编辑器

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/musicvs/article/details/25368273 好吧.我真心全然搞不懂.我如今仅仅只 ...

  3. 《Genesis-3D开源游戏引擎完整实例教程-2D射击游戏篇:简介及目录》(附上完整工程文件)

    G-3D引擎2D射击类游戏制作教程 游戏类型: 打飞机游戏属于射击类游戏中的一种,可以划分为卷轴射击类游戏. 视觉表现类型为:2D 框架简介: Genesis-3D引擎不仅为开发者提供一个3D游戏制作 ...

  4. 值得 Web 开发人员收藏的20个 HTML5 实例教程

    当开始学习如何创建 Web 应用程序或网站的时候,最流行的建议之一就是阅读教程,并付诸实践.也有大量的 Web 开发的书,但光有理论没有实际行动是无用的.现在由于网络的发展,我们有很多的工具可以用于创 ...

  5. 3Ds Max实例教程-制作女战士全过程

    3Ds Max制作“女战神” 作者:Diego Rodríguez 使用软件:3Ds Max,Photoshop 3Ds Max下载:http://wm.makeding.com/iclk/?zone ...

  6. 深度学习与CV教程(14) | 图像分割 (FCN,SegNet,U-Net,PSPNet,DeepLab,RefineNet)

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...

  7. Python导出Excel为Lua/Json/Xml实例教程(一):初识Python

    Python导出Excel为Lua/Json/Xml实例教程(一):初识Python 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出 ...

  8. 值得 Web 开发人员学习的20个 jQuery 实例教程

    这篇文章挑选了20个优秀的 jQuery 实例教程,这些 jQuery 教程将帮助你把你的网站提升到一个更高的水平.其中,既有网站中常用功能的的解决方案,也有极具吸引力的亮点功能的实现方法,相信通过对 ...

  9. Web 开发中应用 HTML5 技术的10个实例教程

    HTML5 作为下一代网站开发技术,无论你是一个 Web 开发人员或者想探索新的平台的游戏开发者,都值得去研究.借助尖端功能,技术和 API,HTML5 允许你创建响应性.创新性.互动性以及令人惊叹的 ...

  10. 《HTML5与CSS3实例教程》

    <HTML5与CSS3实例教程> 基本信息 作者: (美)Brian P. Hogan 译者: 卢俊祥 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:97871153634 ...

随机推荐

  1. Python基础——字符编码、文件处理

    文章目录 字符编码 一 引入 二 知识储备 2.1 三大核心硬件 2.2 文本编辑器读取文件内容的流程 2.3 python解释器执行文件的流程 2.4 总结 三.字符编码介绍 3.1 什么是字符编码 ...

  2. Python基础——深浅拷贝、python内存泄露、你并不了解的format、decimal

    文章目录 深浅拷贝 先看赋值运算 浅拷贝copy 深拷贝deepcopy 相关面试题 python内存泄露 起因 方案 编写安全的代码 弱引用 你并不了解的format.decimal format格 ...

  3. 成本阶问题:财务模块axcr004合计金额检核表第18行合计金额与明细差异过大问题处理?

    财务模块axcr004合计金额检核表第18行合计金额与明细差异过大问题处理? 可能原因:生产开立工单时元件未建在生产料件BOM明细中,导致成本阶没有算到,需要手动更改成本阶. 公式: 处理办法:修改成 ...

  4. buu pwn wp(持续更新)

    1.warmup_csaw_2016 main函数如下 __int64 __fastcall main(int a1, char **a2, char **a3) { char s[64]; // [ ...

  5. Go 函数多返回值错误处理与error 类型介绍

    Go 函数多返回值错误处理与error 类型介绍 目录 Go 函数多返回值错误处理与error 类型介绍 一.error 类型与错误值构造 1.1 Error 接口介绍 1.2 构造错误值的方法 1. ...

  6. OpenTiny Vue 支持 Vue2.7 啦!

    你好,我是 Kagol. 前言 上个月发布了一篇 Vue2 升级 Vue3 的文章. 少年,该升级 Vue3 了! 里面提到使用了 ElementUI 的 Vue2 项目,可以通过 TinyVue 和 ...

  7. Kubernetes---修改证书可用年限

    kubeadm---修改apiserver证书有效期 源码编译自签证书: 需要有go环境,从github源码仓库拉取k8s对应版本的源码进行修改/编译.覆盖原来的kubeadm即可. 1.查询证书可用 ...

  8. 模拟ASP.NET Core MVC设计与实现

    前几天有人在我的<ASP.NET Core框架揭秘>读者群跟我留言说:"我最近在看ASP.NET Core MVC的源代码,发现整个系统太复杂,涉及的东西太多,完全找不到方向,你 ...

  9. Kotlin协程系列(一)

    一.协程的定义 最近看了一本有关kotlin协程的书籍,对协程又有了不一样的了解,所以准备写一个关于kotlin协程系列的文章. 言归正传,我们在学习一个新东西的时候,如果连这个东西"是什么 ...

  10. 【题解】HD2016.X1,HD2016.X3,HD2016.X4,HD2016.X5

    [HD2016.X1] 价钱统计 题目描述 夏天到了,超市里摆满了各种各样的应季水果.现在知道:西瓜的价钱是每斤 1.2 元:桃子的价钱是每斤 3.5 元:葡萄的价钱是每斤 4.5 元:苹果的价钱是每 ...