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…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...