35. UE5 RPG制作火球术技能
接下来,我们将制作技能了,总算迈进了一大步。首先回顾一下之前是如何实现技能触发的,然后再进入正题。
如果想实现我之前的触发方式的,请看此栏目的31-33篇文章,讲解了实现逻辑,这里总结一下:
- 首先创建一个DataAsset用于存储InputAction和GameplayTag对应的数据
- 在触发InputAction的时候,将GameplayTag作为参数去调用输入回调
- 在技能身上绑定对应的GameplayTag,在回调中遍历角色身上的应用的技能,如果Tag相同,则激活技能。
现在技能可以被激活了,需要我们实现技能内的逻辑,接下来,我们将从简单的开始实现,那就是火球术。
要创建技能的完整内容我们需要:
- 创建一个Actor,在里面增加一个碰撞体和一个发射器,用于实现子弹移动和碰撞检测。
- 创建一个基于技能基类的用于发射火球的技能,通过里面逻辑进行动画播放和火球发射。
创建Projectile类
首先创建一个Projectile类,继承Actor,可以放置到场景中。并在内部实现碰撞检测和发射器组件。

打开以后,将里面的Tick函数删除,我们不需要每帧更新
public: // Called every framevirtual void Tick(float DeltaTime) override;
将其每帧更新设置为false
PrimaryActorTick.bCanEverTick = false;
并且,将此类设置为在服务器运行
bReplicates = true; //此类在服务器运行,然后复制到每个客户端
首先,我们添加一个碰撞体,这里添加了一个球型碰撞体
private:UPROPERTY(VisibleAnywhere)TObjectPtr<USphereComponent> Sphere;
在构造函数中,对碰撞体进行初始化
//初始化碰撞体Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");SetRootComponent(Sphere); //设置其为根节点,Sphere->SetCollisionEnabled(ECollisionEnabled::QueryOnly); //设置其只用作查询使用Sphere->SetCollisionResponseToChannels(ECR_Ignore); //设置其忽略所有碰撞检测Sphere->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Overlap); //设置其与世界动态物体产生重叠事件Sphere->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Overlap); //设置其与世界静态物体产生重叠事件Sphere->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap); //设置其与Pawn类型物体产生重叠事件
接着增加对应的碰撞检测回调,这个回调函数内部实现我们将在后续实现
void OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
然后再BeginPlay回调用,触发重叠时,绑定此回调
Sphere->OnComponentBeginOverlap.AddDynamic(this, &AProjectile::OnSphereOverlap);
接着,我们创建一个发射组件,发射组件通常用于控制投射物的移动,例如子弹或火箭。这个组件通常负责处理投射物的速度、加速度、路径等。
public: UPROPERTY(VisibleAnywhere)TObjectPtr<UProjectileMovementComponent> ProjectileMovement;
在构造函数中对其进行初始化
//创建发射组件ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>("ProjectileMovement");ProjectileMovement->InitialSpeed = 550.f; //设置初始速度ProjectileMovement->MaxSpeed = 550.f; //设置最大速度ProjectileMovement->ProjectileGravityScale = 0.f; //设置重力影响因子,0为不受影响
接下来,编译打开UE,我们创建一个对应的蓝图

打开以后,如果左侧有我们创建的对应的组件

碰撞体的碰撞类型,也是按我们的设置来的

在根节点(碰撞体)下面添加一个Niagara组件,用于播放粒子特效

添加上对应的Nigara粒子特效,可以放置到场景中查看效果

创建ProjectileSpell
ProjectileSpell是基于技能类创建的子类,我们可以查看源码对基类增加更多的了解,这里我对基类的h文件进行的翻译:
UE5 GameplayAbility 源码定义解析
炮弹创建好了,但是它没有发射器,所以我们接下来实现一下火球的发射器,在里面实现角色发射动画,以及可以在内部实现对火球的发射位置和发射朝向的设置。
首先基于之前创建的技能基类创建一个子类,命名为ProjectileSpell,我们将其作为这种炮弹类的技能的特定类型的技能类

在函数内部,我们首先添加了一个保护函数,覆盖父类的ActivateAbility,这是一个回调函数,在技能激活时,会触发此回调
回调中会返回四个参数,技能实例句柄(可以用此获取实例),激活角色的相关信息,技能激活的相关信息(手动激活还是自动激活,按键激活),激活事件以及传递的数据。
protected:virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;
我们在实现这里先打印一条Log用于测试运行顺序,接着在蓝图中也会打印。
void UProjectileSpell::ActivateAbility(const FGameplayAbilitySpecHandle Handle,const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo,const FGameplayEventData* TriggerEventData)
{Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);UKismetSystemLibrary::PrintString(this, FString("在c++中打印数据"), true, true, FLinearColor::Blue, 3);
}
接着编译项目,创建一个基于ProjectileSpell的技能蓝图

在技能蓝图中,设置鼠标左键触发

在触发技能激活回调中,触发打印

需要在角色创建的时候将技能蓝图应用,所以,我们在角色蓝图中属性中设置技能应用。

运行,点击敌人,发现打印,看来在c++中输入汉字不支持,顺序就是先调用了蓝图,然后又调用的c++内的回调。

接下来,我们实现使用技能发射火球,首先在类里增加一个属性来设置火球的类,在技能激活时去实例化
UPROPERTY(EditAnywhere, BlueprintReadOnly)TSubclassOf<AProjectile> ProjectileClass;
我们还需要一个位置去发射火球,这个位置我们选择武器上面的一个骨骼节点作为位置。在之前的战斗接口类里面增加一个获取骨骼插槽位置的函数,这个函数需要在子类去覆盖
virtual FVector GetCombatSocketLocation();
然后再角色基类中,添加一个设置骨骼节点名称的变量,并覆盖这个函数
UPROPERTY(EditAnywhere, Category = "Combat")FName WeaponTipSocketName;virtual FVector GetCombatSocketLocation() override;
函数实现,直接调用获取骨骼接口名称的位置
FVector ACharacterBase::GetCombatSocketLocation()
{return Weapon->GetSocketLocation(WeaponTipSocketName);
}
有了火球术的类,有了发射的位置,我们就可以生成火球了,接着回到ProjectileSpell里面,首先将控制的Actor转换为战斗接口
if (ICombatInterface* CombatInterface = Cast<ICombatInterface>(GetAvatarActorFromActorInfo()))
如果转换成功,那么我们就可以通过接口函数去获取位置信息,创建一个变换变量
FTransform SpawnTransform;SpawnTransform.SetLocation(CombatInterface->GetCombatSocketLocation());SpawnTransform.SetRotation(GetAvatarActorFromActorInfo()->GetActorQuat());
现在,我们火球类有了,位置变换有了,最后,使用通用方法生成火球,
//SpawnActorDeferred将异步创建实例,在实例创建完成时,相应的数据已经应用到了实例身上GetWorld()->SpawnActorDeferred<AProjectile>(ProjectileClass,SpawnTransform,GetOwningActorFromActorInfo(),Cast<APawn>(GetOwningActorFromActorInfo()),ESpawnActorCollisionHandlingMethod::AlwaysSpawn);
如果你是异步生成的Actor,还需要调用FinishSpawning函数确保设置正确的应用到actor上面。
//确保变换设置被正确应用
Projectile->FinishSpawning(SpawnTransform);
首先在技能上面设置需要生成的火球术的类

设置完成以后,我们需要设置使用的插槽 ,也可以在武器骨骼上面创建插槽使用。

案例里面武器顶部有个TipSocket插槽,我们将使用此位置发射火球。

记得在角色设置里面设置对应骨骼插槽名称。

到现在,我们实现了一个最基础的火球术,接着运行项目查看效果。

在技能里,我使用了蒙太奇播放角色动画,在蒙太奇播放完成结束当前技能,如果技能结束还可以再次触发。

现在,我们实现了一个最简单的通过火球术技能,效果很差,接下来,我们将接着实现火球术,并让效果看起来更合理,并在后面实现对敌人造成伤害。
相关文章:
35. UE5 RPG制作火球术技能
接下来,我们将制作技能了,总算迈进了一大步。首先回顾一下之前是如何实现技能触发的,然后再进入正题。 如果想实现我之前的触发方式的,请看此栏目的31-33篇文章,讲解了实现逻辑,这里总结一下: …...
计算机网络 TCP/IP体系 物理层
一. TCP/IP体系 物理层 1.1 物理层的基本概念 物理层作为TCP/IP网络模型的最低层,负责直接与传输介质交互,实现比特流的传输。 要完成物理层的主要任务,需要确定以下特性: 机械特性:物理层的机械特性主要涉及网络…...
微服务相关
1. 微服务主要七个模块 中央管理平台:生产者、消费者注册,服务发现,服务治理,调用关系生产者消费者权限管理流量管理自定义传输协议序列化反序列化 2. 中央管理平台 生产者A在中央管理平台注册后,中央管理平台会给他…...
虚拟机下如何使用Docker(完整版)
Docker详细介绍: Docker 是一款开源的应用容器引擎,由Docker公司最初开发并在2013年发布。Docker的核心理念源自于操作系统级别的虚拟化技术,尤其是Linux上的容器技术(如LXC),它为开发人员和系统管理员提供…...
asp.net core 依赖注入后的服务生命周期
ASP.NET Core 依赖注入(DI)容器支持三种服务的生命周期选项,它们定义了服务实例的创建和销毁的时机。理解这三种生命周期对于设计健壯且高效的应用程序非常重要: 瞬时(Transient): 瞬时服务每次…...
交换排序:冒泡排序和快速排序
冒泡排序 思路 通过多次遍历数组,比较相邻的元素,并交换它们,使得每次遍历结束后,最大(或最小)的元素都“冒泡”到数组的末尾 实现 public class Main {public static void main(String[] args) {int[] …...
聊天机器人ChatGPT指导下的论文写作
ChatGPT无限次数:点击直达 聊天机器人ChatGPT指导下的论文写作 引言 随着人工智能技术的不断发展,聊天机器人在各个领域得到了广泛应用。其中,ChatGPT作为一个先进的自然语言处理模型,为各种文本生成任务提供了强大的支持。在学术界…...
康谋技术 | 深入探讨:自动驾驶中的相机标定技术
随着自动驾驶技术的快速发展,多传感器的数据采集和融合可以显著提高系统的冗余度和容错性,进而保证决策的快速性和正确性。在项目开发迭代过程中,传感器标定扮演着至关重要的角色,它位于数据采集平台与感知融合算法之间࿰…...
如何在 Ubuntu 上启用 IPv6
一、前提条件 一台安装了 Ubuntu 22.04 的计算机具有 sudo 权限的用户账户已连接到支持 IPv6 的网络 二、检查系统是否支持 IPv6 在启用 IPv6 之前,首先要确保您的系统支持 IPv6。要检查内核是否启用了 IPv6,可以运行以下命令: cat /proc/…...
Mac电脑上有什么好玩的格斗游戏 《真人快打1》可以在苹果电脑上玩吗
你是不是喜欢玩格斗游戏?你是不是想在你的Mac电脑上体验一些刺激和激烈的对战?在这篇文章中,我们将介绍Mac电脑上有什么好玩的格斗游戏,以及《真人快打1》可以在苹果电脑上玩吗。 一、Mac电脑上有什么好玩的格斗游戏 格斗游戏是…...
【leetcode面试经典150题】55. 逆波兰表达式求值(C++)
【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主,题解使用C语言。(若有使用其他语言的同学也可了解题解思路,本质上语法内容一致&…...
云轴科技ZStack入选中国信通院《高质量数字化转型产品及服务全景图(2023年度)》
近日,由中国互联网协会主办、中国信通院承办的“2024高质量数字化转型创新发展大会”暨“铸基计划”年度会议在北京成功召开。 本次大会发布了2024年度行业数字化转型趋势,总结并展望了“铸基计划”2023年取得的工作成果及2024年的工作规划。同时&#…...
Workerman开启ssl方法如下
参考地址 Workerman开启ssl方法如下-遇见你与你分享 准备工作: 1、Workerman版本不小于3.3.7 2、PHP安装了openssl扩展 3、已经申请了证书(pem/crt文件及key文件)放在了/etc/nginx/conf.d/ssl下 4、配置文件 location /wss { proxy_set…...
如何防止服务器被攻击
如何防止服务器被攻击 第1步:切断网络; 服务器的攻击来源都必须通过互联网,一旦切断网络,它们就失去了攻击的入口,你可以通过切断网络的方式,以最快的速度切断攻击源,保护服务器所在网络的其他主机服务器。…...
18 统计网站每日的访问次数
1.将竞赛的数据上传HDFS,查看数据的格式 通过浏览器访问hdfs,查看该文档前面的部分数据 每条数据的字段值之间使用逗号隔开的 ,最终时间是第五个自动,获取第五个字段值的中的年月日。 2.通过Idea创建项目mr-raceData ,基础的配置 修改pom.xml,添加依赖 …...
Java PDF文件流传输过程中速度很慢,如何解决?
专栏集锦,大佬们可以收藏以备不时之需: Spring Cloud 专栏:http://t.csdnimg.cn/WDmJ9 Python 专栏:http://t.csdnimg.cn/hMwPR Redis 专栏:http://t.csdnimg.cn/Qq0Xc TensorFlow 专栏:http://t.csdni…...
MCU最小系统晶振模块设计
单片机的心脏:晶振 晶振模块 单片机有两个心脏,一个是8M的心脏,一个是32.768的心脏 8M的精度较低,所以需要外接一个32.768khz 为什么是8MHZ呢,因为内部自带的 频率越高,精度越高,功耗越大&am…...
ELK及ELFK排错
目录 一、ELK及ELFK排错思路 1.1filebeat侧排查 1.2logstash侧排查 1.3ES、kibana侧问题 一、ELK及ELFK排错思路 1.1filebeat侧排查 第一步:排查filebeat上的配置文件有没有写错,filebeat的配置文件是yml文件,一定要注意格式。 第二步…...
『Django』创建app(应用程序)
theme: smartblue 本文简介 点赞 关注 收藏 学会了 在《『Django』环境搭建》中介绍了如何搭建 Django 环境,并且创建了一个 Django 项目。 在刚接触 Django 时有2个非常基础的功能是需要了解的,一个是“app”(应用程序),另一个是 url(路由…...
Docker安装(一)
一、安装Docker 服务器系统:centos 7 1.本地有docker的首先卸载本机docker yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \dock…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...
归并排序:分治思想的高效排序
目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...
