116. UE5 GAS RPG 实现击杀掉落战利品功能

这一篇,我们实现敌人被击败后,掉落战利品的功能。首先,我们将创建一个新的结构体,用于定义掉落体的内容,方便我们设置掉落物。然后,我们实现敌人死亡时的掉落函数,并在蓝图里实现对应的逻辑,在场景里生成掉落物。最后,让掉落物动起来,显得掉落物需要玩家赶紧去拾取的感觉。

添加新的资产结构体

为了实现对敌人掉落战利品的配置,我们需要创建一个新的类,作为配置掉落物的新的资产类。
在这里插入图片描述
命名为战利品类
在这里插入图片描述
在类里,我们首先添加一个结构体,用于设置一种物品的掉落内容和几率。

USTRUCT(BlueprintType)
struct FLootItem
{GENERATED_BODY()//战利品在场景中的显示效果UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="LootTiers|Spawning")TSubclassOf<AActor> LootClass;//战利品生成几率UPROPERTY(EditAnywhere, Category="LootTiers|Spawning")float ChanceToSpawn = 0.f;//物品生成的最大数量UPROPERTY(EditAnywhere, Category="LootTiers|Spawning")int32 MaxNumberToSpawn = 0.f;//修改物品生成等级,false则使用敌人等级UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="LootTiers|Spawning")bool bLootLevelOverride = true;
};

然后在类里,我们增加一个数组,开发者可以配置多个掉落物,然后添加一个函数,用于获取当前可以生成的战利品数组。

UCLASS()
class RPG_API ULootTiers : public UDataAsset
{GENERATED_BODY()public://获取需要生成的战利品数据UFUNCTION(BlueprintCallable)TArray<FLootItem> GetLootItems();UPROPERTY(EditDefaultsOnly, Category="LootTiers|Spawning")TArray<FLootItem> LootItems;
};

在函数实现这里,我们创建了一个新的数组,用于根据概率计算每个物品的是否可掉落,物品可以设置多个,所以,我们需要两层嵌套循环,如果当前可掉落,那么我们将其添加到返回数组里。最后返回。

TArray<FLootItem> ULootTiers::GetLootItems()
{TArray<FLootItem> ReturnItems;for(const FLootItem Item : LootItems){for(int32 i=0; i<Item.MaxNumberToSpawn; ++i){if(FMath::RandRange(1.f, 100.f) < Item.ChanceToSpawn){FLootItem NewItem;NewItem.LootClass = Item.LootClass;NewItem.bLootLevelOverride = Item.bLootLevelOverride;ReturnItems.Add(NewItem);}}}return ReturnItems;
}

实现配置和触发掉落逻辑

然后,我们需要一个能够去获取配置好的数据资产的地方,最方便的就是放到GameMode里,我们在GameMode类里添加一个配置,可以在蓝图配置使用哪一个数据资产

	//战利品数据配置UPROPERTY(EditDefaultsOnly, Category="Loot Tiers")TObjectPtr<ULootTiers> LootTiers;

为了方便获取数据资产,我们在蓝图函数库里增加一个函数,用于获取数据资产

	/*** 获取生成的战利品数据资产,此数据会配置到GameMode上* @param WorldContextObject  一个世界场景的对象,用于获取当前所在的世界* @return 战利品数据** @note 敌人死亡后,所需生成的战利品*/UFUNCTION(BlueprintCallable, Category="RPGAbilitySystemLibrary|CharacterClassDefaults", meta=(DefaultToSelf = "WorldContextObject"))static ULootTiers* GetLootTiers(const UObject* WorldContextObject);

函数实现,我们将获取到GameMode,并从GameMode身上获取到数据资产

ULootTiers* URPGAbilitySystemLibrary::GetLootTiers(const UObject* WorldContextObject)
{//获取到当前关卡的GameMode实例const ARPGGameMode* GameMode = Cast<ARPGGameMode>(UGameplayStatics::GetGameMode(WorldContextObject));if(GameMode == nullptr) return nullptr;//返回敌人战利品配置,需要设置到GameMode上return  GameMode->LootTiers;
}

最后,我们要在敌人类里实现掉落逻辑,我们增加一个函数,这个函数需要在蓝图里实现逻辑

	//生成战利品UFUNCTION(BlueprintImplementableEvent)void SpawnLoot();

然后在触发死亡逻辑时,我们调用此函数来生成战利品

在这里插入图片描述

添加蓝图

代码方便,我们完成了,接着,我们要在编辑器里,添加一个新的数据资产
在这里插入图片描述
资产类型使用我们创建的战利品资产
在这里插入图片描述
我们将其和之前的资产放到一块
在这里插入图片描述
然后,在资产里,我们将之前制作的药瓶和水晶(持续回血)添加到战利品里,掉落概率设置为100,并且要使用敌人等级掉落。
在这里插入图片描述
接着将其设置到GameMode蓝图里
在这里插入图片描述
我们在敌人蓝图基类里实现统一的掉落战利品机制,首先通过蓝图库函数获取到数据资产实例,然后通过GetLootItems获取到需要生成的掉落物
在这里插入图片描述
然后创建一个蓝图函数,用于通过蓝图函数库,来设置掉落物的转向。
在这里插入图片描述
然后我们将其设置为纯函数,这样,不需要通过执行箭头调用。
在这里插入图片描述
然后将转向存储起来方便后续使用
在这里插入图片描述
然后,我们通过一个定时器,让物品掉落持续生成,这样可以防止卡顿,并且物品有一个个生成的效果,我们在设置定时器时,直接调用一次此事件。
在这里插入图片描述
接着就是生成战利品的自定义事件,我们通过索引,从返回的数组里获取到需要生成的对应的数据,并计算出物品掉落位置,最后生成Actor
在这里插入图片描述
我们创建获取变换的纯函数,通过转向对敌人位置进行一个朝向在一定范围内随机偏移,并使用旋转的朝向。
在这里插入图片描述
在创建Actor后,我们需要更新掉落物的等级,如果此物品需要修改等级,那么我们将通过此函数内的逻辑进行修改
在这里插入图片描述
函数内,我们首先判断是否需要修改,然后将其转换为场景物品的基类,然后判断当前物品是否存在,最后将敌人等级应用到掉落物身上。
在这里插入图片描述
最后一步,就是修改索引,每调用一次,我们将索引+1,下次再调用此事件时,将会生成下一个坐标的物品,如果索引超过或等于数组长度时,我们将结束定时器,完成掉落物的生成。
在这里插入图片描述
最后展示一下完成的蓝图连线

在这里插入图片描述

然后进入关卡打怪测试效果
在这里插入图片描述

关于掉落物的一些扩展

如果后续扩展的话,我考虑对于每个大关卡创建单独的一套掉落,然后在数组资产里增加几个数组,比如效果,使用小怪的一套掉落,而精英怪使用精英怪的一套掉落,最后是boss的掉落,使用boss的一套掉落逻辑。
然后获取掉落时,可以根据敌人品质,去获取不同的掉落,我们当然没必须单独为敌人去配置掉落。BOSS除外,我们当然可以对一些特殊BOSS去配置单独的掉落,比如关卡的最终BOSS掉落,以及一些特殊怪物掉落。

实现掉落物自动旋转和悬浮效果

为了实现这个效果,我们要在掉落物的基类RPGEffectActor里增加一些属性和函数,用于实现此效果
要实现这个功能,我们增加一批函数,用于实现此功能

	// 计算后的Actor所在的位置UPROPERTY(BlueprintReadWrite)FVector CalculatedLocation;// 计算后的Actor的旋转UPROPERTY(BlueprintReadWrite)FRotator CalculatedRotation;// Actor是否帧更新旋转UPROPERTY(BlueprintReadWrite, Category="Pickup Movement")bool bRotates = false;// Actor每秒旋转的角度UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")float RotationRate = 45.f;// Actor是否更新位置UPROPERTY(BlueprintReadWrite, Category="Pickup Movement")bool bSinusoidalMovement = false;// 正弦值-1到1,此值为调整更新移动范围UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")float SineAmplitude = 1.f;// 此值参与正弦运算,默认值为1秒一个循环(2PI走完一个正弦的循环,乘以时间,就是一秒一个循环,可用于调整位置移动速度)UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")float SinePeriod = 1.f; //2 * PI//调用此函数,Actor开始自动更新上下位置UFUNCTION(BlueprintCallable)void StartSinusoidalMovement();//调用此函数,Actor开始自动旋转UFUNCTION(BlueprintCallable)void StartRotation();
private://当前掉落物的存在时间,可以通过此时间实现动态效果float RunningTime = 0.f;// Actor生成的默认初始位置,在Actor动态浮动时,需要默认位置作为基础位置FVector InitialLocation;// 每一帧更新Actor的位置和转向void ItemMovement(float DeltaSeconds);

我们还需要用到帧更新函数

virtual void Tick(float DeltaSeconds) override;

在事件开始时,我们将掉落物的默认位置和旋转保存,并设置计算后的属性,我们需要在后续使用它更新Actor

void ARPGEffectActor::BeginPlay()
{Super::BeginPlay();//设置初始位置InitialLocation = GetActorLocation();CalculatedLocation = InitialLocation;CalculatedRotation = GetActorRotation();
}

我们需要在帧更新了去保存当前效果的执行时间,并调用更新函数

void ARPGEffectActor::Tick(float DeltaSeconds)
{Super::Tick(DeltaSeconds);//更新当前Actor的存在时间RunningTime += DeltaSeconds;ItemMovement(DeltaSeconds);
}

在更新函数里,我们根据变量判断是否需要更新,来对转向和位置更新,这里需要提到的是,位置更新用到了正弦三角函数进行更新

void ARPGEffectActor::ItemMovement(float DeltaSeconds)
{//更新转向if(bRotates){const FRotator DeltaRotation(0.f, DeltaSeconds * RotationRate, 0.f);CalculatedRotation = UKismetMathLibrary::ComposeRotators(CalculatedRotation, DeltaRotation);}//更新位置if(bSinusoidalMovement){const float Sine = SineAmplitude * FMath::Sin(RunningTime * SinePeriod * 6.28318f);CalculatedLocation = InitialLocation + FVector(0.f, 0.f, Sine);}
}

你会发现上面的变量无法在蓝图面板直接设置,那么如何将其设置为true呢,我们通用函数将其设置为true

void ARPGEffectActor::StartSinusoidalMovement()
{bSinusoidalMovement = true;InitialLocation = GetActorLocation();CalculatedLocation = InitialLocation;
}void ARPGEffectActor::StartRotation()
{bRotates = true;CalculatedRotation = GetActorRotation();
}

后续效果我们需要在蓝图里实现,所以,我们创建一个拾取的基类,然后将所有可掉落物都继承此蓝图,没必要在每个蓝图里实现一遍
在这里插入图片描述
我们在拾取物基类里,创建一个时间轴,来实现掉落物的从无到有的效果,并通过时间轴的更新实现一些位置更新,和缩放效果。在时间轴播放完成后,我们调用开始旋转和开始移动的默认效果。
在这里插入图片描述
时间轴里,我们增加了两个轨道,用于分别更新位置和缩放使用
在这里插入图片描述
在帧更新里,我们通过计算后的位置和旋转更新Actor即可
在这里插入图片描述

以下是拾取物的表现效果

在这里插入图片描述

添加音效

最后一个功能,我们在Actor里添加一些音效,来实现一些点缀效果。
首先在Actor增加一个变量,设置音效基础类型
在这里插入图片描述
然后找到对应的音效
在这里插入图片描述
设置给变量

在这里插入图片描述
在更新位置和缩放后(我折叠成了一个函数),我们通过修改位置的值,判断如果大于0.3时,执行一次模拟触碰到地面的音效
在这里插入图片描述
然后在事件开始时增加一个生成的音效

在这里插入图片描述
在销毁时,播放一个拾取的音效。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/485892.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图像生成-扩散模型的经典之作DDPM

论文&#xff1a;https://arxiv.org/pdf/2006.11239 项目&#xff1a;https://github.com/hojonathanho/diffusion Denoising Diffusion Probabilistic Models (DDPM) 是一种生成模型&#xff0c;它通过一系列逐步添加噪声的过程将数据点映射到一个简单的先验分布&#xff08;…

【Axure视频教程】中继器表格——筛选后的条件判断

今天教大家在Axure制作中继器表格筛选以及筛选后条件交互的原型模板&#xff0c;我们可以在输入框里输入员工姓名&#xff0c;点击查询按钮后可以筛选出对应的数据&#xff0c;筛选后会进行条件判断&#xff0c;如果筛选不到任何数据&#xff0c;就会显示提示弹窗。这个原型模板…

GDPU 人工智能 期末复习

1、python基础 2、回归、KNN、K-Means、搜索方法思想及算法实现步骤 3、知识表示基本概念 4、状态空间的相关概念、表示方法及应用 5、图搜索策略及应用 6、问题归约概念、与或图搜索、博弈树搜索与剪枝 7、决策树、贝叶斯决策算法及其应用 8、神经网络与深度学习基本概念 一、…

几个Linux系统安装体验: 龙蜥服务器系统

本文介绍龙蜥服务器系统&#xff08;AnolisOS&#xff09;的安装。 下载 下载地址&#xff1a; https://openanolis.cn/download 选定版本为8.6。 本文下载的文件名称为AnolisOS-8.6-x86_64-minimal.iso&#xff0c;体积约2.2GB。另&#xff1a;AnolisOS-8.6-QU1-x86_64-dv…

Unity 设计模式-策略模式(Strategy Pattern)详解

策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;定义了一系列算法&#xff0c;并将每种算法封装到独立的类中&#xff0c;使得它们可以互相替换。策略模式让算法可以在不影响客户端的情况下独立变化&#xff0c;客户端通过与这些策略对象进…

阿拉丁论文助手:一键点亮学术之路

在学术研究的海洋中&#xff0c;每一位学者都渴望拥有一盏能够照亮前行道路的神灯。阿拉丁论文助手&#xff0c;正是这样一盏神奇的灯&#xff0c;它以其先进的人工智能技术和丰富的学术资源&#xff0c;为学者们的学术写作提供了全方位的支持。 一、阿拉丁论文助手简介 阿拉丁…

YOLOv10改进,YOLOv10添加U-Netv2分割网络中SDI信息融合模块,助力小目标检测

摘要 理论介绍 SDI模块的架构: 平滑卷积(SmoothConv):用于平滑特征图,帮助减少噪声并使得特征更加稳定。Hadamard积:用于在特征图中进行逐元素相乘(点乘),以加强语义信息和细节信息的融合。通道注意力(ChannelAttention):利用通道注意力机制来自动关注重要的特征通…

解锁 AI 潜能 - ChatGPT等大模型提示词技巧

在人工智能领域&#xff0c;ChatGPT 等大语言模型正在重新定义我们的工作和生活方式。这些强大的 AI 大模型 能够理解自然语言并生成高质量的内容&#xff0c;无论是撰写文案、解决问题&#xff0c;还是数据分析&#xff0c;都展现了卓越的表现。如何高效使用这些工具&#xff…

基于Java和Vue开发的漫画阅读软件漫画阅读小程序漫画APP

前景分析 受众广泛&#xff1a;漫画的受众群体广泛&#xff0c;不仅限于青少年&#xff0c;还涵盖了成年人等多个年龄层和社会阶层。漫画文化在全球范围内的影响力不断扩大&#xff0c;未来漫画软件创业可以考虑全球市场的拓展。 市场需求大&#xff1a;数字化阅读趋势下&…

GEE:CCDC 分类组件,对每个分段进行分类

作者:CSDN @ _养乐多_ 连续变化检测与分类(Continuous Change Detection and Classification, CCDC) 利用了时间序列拟合来对影像中的像素值随时间的变化趋势建模。每一段模型代表一个时间段内的地表覆盖类型和状态。 本文将解释如何在谷歌地球引擎(Google Earth Engine,…

vue3+elementPlus封装的一体表格

目录结构 源码 exportOptions.js export default reactive([{label: 导出本页,key: 1,},{label: 导出全部,key: 2,}, ])index.vue <template><div class"flex flex-justify-between flex-items-end"><div><el-button-group><slot name…

【计算机组成原理】CPU概述

文章目录 CPU主要功能CPU总体结构模型运算部件缓存部件寄存器组(堆)控制器时序部件 CPU主要功能 CPU是取指令并执行指令的部件 CPU总体结构模型 运算部件 运算部件用于对操作数进行运算&#xff0c;主要是算术运算/逻辑运算 运算部件的基本组成如下&#xff1a; 缓存部件 缓…

鸿蒙开发——键值型数据库的基本使用与跨设备同步

1、简 述 ❓ 什么是键值型数据库 键值型数据库&#xff08;KV-Store&#xff09;是一种非关系型数据库&#xff0c;其数据以“键值”对的形式进行组织、索引和存储&#xff0c;其中“键”作为唯一标识符。 键值型数据库适合很少数据关系和业务关系的业务数据存储。 另外&#…

零基础认识:交换机,子网掩码,默认网关,以及路由器,IP地址,MAC地址

图解 物理层&#xff1a;使用MAC解决设备的身份证问题 通信的原始时代 很久很久之前&#xff0c;你不与任何其他电脑相连接&#xff0c;孤苦伶仃。 直到有一天&#xff0c;你希望与另一台电脑 B 建立通信&#xff0c;于是你们各开了一个网口&#xff0c;用一根网线连接了起来…

【Canvas与标牌】Water Outages(停水)标牌

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>Wate Outages停水标志 Draft1</title><style type"tex…

CentOS 7 上安装 MySQL 8.0.40 (二进制安装)

要在 CentOS 7 上安装 MySQL 8.0.40&#xff0c;按照以下步骤操作&#xff1a; 下载安装包。 https://dev.mysql.com/downloads/mysql/ 下载之前查看系统c版本 解压安装包 首先&#xff0c;解压下载的 .tar.xz 安装包。 cd /path/to/your/downloads tar -xvf mysql-8.0…

汽车产业数字化转型:协同创新破解挑战,平衡安全与流通

在数字经济时代的浪潮中&#xff0c;数据资源和数据信息已成为驱动各行各业转型升级的“新石油”。汽车产业&#xff0c;作为国民经济的重要支柱&#xff0c;正经历着前所未有的变革。随着数字化创新和转型的深入&#xff0c;数据在汽车全产业链中的作用和价值日益凸显。在这个…

windows 脚本批量管理上千台服务器实战案例

如果你们有接触服务器&#xff0c;都是知道服务器有BMC管理界面的&#xff0c;这几天我在做项目中&#xff0c;需要不断的开关机服务器&#xff0c;如果一两台服务器登录BMC界面重启服务器还好&#xff0c;如果服务器数量非常的庞大&#xff0c;成百上千台&#xff0c;我们不可…

yarn : 无法加载文件 C:\Users\L\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁

关于执行安装yarn命令后执行yarn -v报错&#xff1a; 先确认执行安装yarn命令是否有误 # 安装yarn npm install yarn -g 终端输入set-ExecutionPolicy RemoteSigned 当然如果yarn -v仍然执行失败&#xff0c;考虑使用管理员方式运行IDEA&#xff0c; 注&#xff1a;如上操作…

Redis 数据结结构(一)—字符串、哈希表、列表

Redis&#xff08;版本7.0&#xff09;的数据结构主要包括字符串&#xff08;String&#xff09;、哈希表&#xff08;Hash&#xff09;、列表&#xff08;List&#xff09;、集合&#xff08;Set&#xff09;、有序集合&#xff08;Sorted Set&#xff09;、超日志&#xff08…