UE5学习笔记24-添加武器弹药
一、给角色的武器添加弹药
1.创建界面,根据笔记23的界面中添加

2.绑定界面控件
UPROPERTY(meta = (Bindwidget))UTextBlock* WeaponAmmoAmount;UPROPERTY(meta = (Bindwidget))UTextBlock* CarriedAmmoAmount;
3.添加武器类型枚举
3.1创建武器类型枚举头文件

3.2创建文件时,默认添加的路径是在Intermediate/ProjectFiles文件夹中,通过#include 包含头文件时会找不到对应的头文件,需要更改路径,我是将所有武器类的C++文件放到Weapon文件夹中,所以我将武器类型头文件放到了Weapon文件夹中。


3.3创建枚举
#pragma onceUENUM(BlueprintType)
enum class EWeapoType : uint8
{EWT_AssaultRifle UMETA(DisplayName = "Assault Rifle"),EWT_MAX UMETA(DisplayName = "DefaultMAX"),
};
3.4创建武器弹药数量,捡起武器的声音
/*** 弹药数量 */UPROPERTY(EditAnywhere, ReplicatedUsing = OnRep_Ammo)int32 Ammo;//弹药数量UFUNCTION()void OnRep_Ammo();UPROPERTY(EditAnywhere)int32 MagCapacity;//最大弹药数量void SpendRound();void SetHUDAmmo();UPROPERTY()class ABlasterCharacter* BlasterOwnerCharacter; // 当前持有武器的角色UPROPERTY()class ABlasterPlayerController* BlasterOwnerController; // 当前持有武器的角色控制器UPROPERTY()EWeapoType WeaponType;/*** 武器的声音*/UPROPERTY(EditAnywhere)class USoundCue* EquipSound;bool IsEmpty();
FORCEINLINE EWeapoType GetWeaponType() const { return WeaponType; }
FORCEINLINE int32 GetAmmo() const { return Ammo; }
FORCEINLINE int32 GetMagCapacity() const { return MagCapacity; }
bool AWeapon::IsEmpty()
{return Ammo <= 0;
}void AWeapon::OnRep_Ammo()
{//BlasterOwnerCharacter = BlasterOwnerCharacter == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : BlasterOwnerCharacter;SetHUDAmmo();
}void AWeapon::SpendRound()
{Ammo = FMath::Clamp(Ammo - 1,0,MagCapacity);SetHUDAmmo();
}void AWeapon::SetHUDAmmo()
{BlasterOwnerCharacter = BlasterOwnerCharacter == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : BlasterOwnerCharacter;if (BlasterOwnerCharacter){BlasterOwnerController = BlasterOwnerController == nullptr ? Cast<ABlasterPlayerController>(BlasterOwnerCharacter->Controller) : BlasterOwnerController;if (BlasterOwnerController){BlasterOwnerController->SetHUDWeaponAmmo(Ammo);}}
}
3.5.因为新添加了两个显示弹药数量的地方,所以给PlayerController添加设置界面的函数
void SetHUDWeaponAmmo(int32 Ammo);void SetHUDCarriedAmmo(int32 Ammo);
void ABlasterPlayerController::SetHUDWeaponAmmo(int32 Ammo)
{BlasterHUD = BlasterHUD == nullptr ? Cast<AABasterHUD>(GetHUD()) : BlasterHUD;bool bHUDValid = BlasterHUD &&BlasterHUD->CharacterOverlay &&BlasterHUD->CharacterOverlay->WeaponAmmoAmount;if (bHUDValid){FString AmmoText = FString::Printf(TEXT("%d"), Ammo); // FloorToInt 向下取整BlasterHUD->CharacterOverlay->WeaponAmmoAmount->SetText(FText::FromString(AmmoText));}
}void ABlasterPlayerController::SetHUDCarriedAmmo(int32 Ammo)
{BlasterHUD = BlasterHUD == nullptr ? Cast<AABasterHUD>(GetHUD()) : BlasterHUD;bool bHUDValid = BlasterHUD &&BlasterHUD->CharacterOverlay &&BlasterHUD->CharacterOverlay->CarriedAmmoAmount;if (bHUDValid){FString CarriedAmmoText = FString::Printf(TEXT("%d"), Ammo); // FloorToInt 向下取整BlasterHUD->CharacterOverlay->CarriedAmmoAmount->SetText(FText::FromString(CarriedAmmoText));}
}
3.6添加重新加载弹药功能,当前武器弹药的数量,播放换弹动画的功能
/* 换弹 */UFUNCTION(Server, Reliable)void ServerReload();/* 换弹 *//* 处理换弹 */void HandleReload();/* 处理换弹 *//** 重新加载弹药函数 */void Reload();/** 处理设置完成战斗状态 */UFUNCTION(BlueprintCallable)void FinishReloading();/** 计算重新加载弹药的数量 */int32 AmountToReload();//当前装备的武器弹药UPROPERTY(ReplicatedUsing = OnRep_CarriedAmmo)int32 CarriedAmmo;UFUNCTION()void OnRep_CarriedAmmo();bool CanFire();// 是否可以开火函数UPROPERTY(ReplicatedUsing = OnRep_CombatState)ECombatState CombatState = ECombatState::ECS_Unoccupied;UFUNCTION()void OnRep_CombatState();void InitializeCarriedAmmo();TMap<EWeapoType, int32> CarriedAmmoMap;
void UCombatComponent::OnRep_CarriedAmmo()
{Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;if (Controller){Controller->SetHUDCarriedAmmo(CarriedAmmo);}
}bool UCombatComponent::CanFire()
{if (EquippedWeapon == nullptr) return false;return !EquippedWeapon->IsEmpty() && bCanFire && CombatState == ECombatState::ECS_Unoccupied;
}void UCombatComponent::OnRep_CombatState()
{switch (CombatState){case ECombatState::ECS_Reloading:HandleReload();break;case ECombatState::ECS_Unoccupied:if (bFireButtonPressed){Fire();}break;}
}void UCombatComponent::FinishReloading()
{if (Character == nullptr) return;if (Character->HasAuthority()){CombatState = ECombatState::ECS_Unoccupied;UpdateAmmoValues();}if (bFireButtonPressed){Fire();}
}void UCombatComponent::HandleReload()
{Character->PlayReloadMontage();
}void UCombatComponent::Reload()
{if (CarriedAmmo > 0 && CombatState != ECombatState::ECS_Reloading){ServerReload();}
}void UCombatComponent::ServerReload_Implementation()
{if (Character == nullptr || EquippedWeapon == nullptr) return;CombatState = ECombatState::ECS_Reloading;HandleReload();
}int32 UCombatComponent::AmountToReload()
{if (EquippedWeapon == nullptr) return 0;int32 RoomInMag = EquippedWeapon->GetMagCapacity() - EquippedWeapon->GetAmmo();if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType())){int32 AmountCarried = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];int32 Least = FMath::Min(RoomInMag,AmountCarried);return FMath::Clamp(RoomInMag, 0, Least);}return 0;
}void UCombatComponent::InitializeCarriedAmmo() beginplay中调用需要检查HasAuthority()
{CarriedAmmoMap.Emplace(EWeapoType::EWT_AssaultRifle, StartingARAmmo);
}
3.7.在装备武器时调用
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType())){CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];}Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;if (Controller){Controller->SetHUDCarriedAmmo(CarriedAmmo);}if (EquippedWeapon->EquipSound){UGameplayStatics::PlaySoundAtLocation(this,EquippedWeapon->EquipSound,Character->GetActorLocation());}if (EquippedWeapon->IsEmpty()){Reload();}
3.8.蓝图设置

相关文章:
UE5学习笔记24-添加武器弹药
一、给角色的武器添加弹药 1.创建界面,根据笔记23的界面中添加 2.绑定界面控件 UPROPERTY(meta (Bindwidget))UTextBlock* WeaponAmmoAmount;UPROPERTY(meta (Bindwidget))UTextBlock* CarriedAmmoAmount; 3.添加武器类型枚举 3.1创建武器类型枚举头文件 3.2创建文…...
限制游客在wordpress某分类下阅读文章的数量
在WordPress中实现某个分类下的内容限制游客只能阅读前5篇文章,注册用户可以阅读更多文章的功能,可以通过以下步骤来完成: 1. 安装和激活插件 首先,你可以使用一个插件来简化这个过程。一个常用的插件是 “MemberPress” 或 “R…...
Oracle云主机申请和使用教程:从注册到SSH连接的全过程
今天我要和大家分享如何成功申请Oracle云主机,并进行基本的配置和使用。我知道很多同行的朋友在申请Oracle云主机时都遇到了困难(疑惑abc错误),可能试了很多次都没有成功。现总结一下这些年来的一些注册流程经验,或许你们也能成功申请到自己的…...
芯知识 | NVH-FLASH语音芯片支持平台做语音—打造音频IC技术革新
随着科技的飞速发展,人们对于电子产品的音频性能要求越来越高。在这种背景下,NVH-FLASH系列语音芯片应运而生,作为音频IC领域的一次重大技术革新,NVH-FLASH系列语音芯片凭借其卓越的性能与灵活的支持平台,正逐步引领着…...
机器学习——解释性AI与可解释性机器学习
解释性AI与可解释性机器学习: 理解机器学习模型背后的逻辑 随着人工智能技术的广泛应用,机器学习模型越来越多地被用于决策过程。然而,这些模型,尤其是深度学习模型,通常被视为“黑箱”,难以理解其背后的决策逻辑。解…...
中国全国省市区县汇总全国省市区json省市区数据2024最新
简介 包含全国省市区县数据,共3465个。 全国总共有23个省、5个自治区、4个直辖市、2个特别行政区。 ——更新于2024年10月16日,从2017年开始,已经更新坚持7年 从刚开始1000个左右的城市json,到现在全国省市区县3465个。 本人感觉应该是目前最完善的~ 每年都在更新中,…...
[Linux#67][IP] 报头详解 | 网络划分 | CIDR无类别 | DHCP动态分配 | NAT转发 | 路由器
目录 一. IP协议头格式 学习任何协议前的两个关键问题 IP 报头与有效载荷分离 分离方法 为什么需要16位总长度 如何交付 二. 网络通信 1.IP地址的划分理念 2. 子网管理 3.网络划分 CIDR(无类别域间路由) 目的IP & 当前路由器的子网掩码 …...
路由器原理和静态路由配置
一、路由器的工作原理 根据路由表转发数据 接收数据包→查看目的地址→与路由表进行匹配找到转发端口→转发到该端口 二、路由表的形成 它是路由器中维护的路由条目的集合,路由器根据路由表做路径选择,里面记录了网段ip地址和对应下一跳接口的接口号。…...
UE5 使用Animation Budget Allocator优化角色动画性能
Animation Budget Allocator是UE内置插件,通过锁定动画系统所占CPU的预算,在到达预算计算量时对动画进行限制与优化。 开启Animation Budget Allocator需要让蒙皮Mesh使用特定的组件,并进行一些编辑器设置即可开启。 1.开启Animation Budget…...
Element UI 组件库详解:从入门到精通
在追求统一且流畅的用户体验时,开发者们常常选择使用 UI 组件库来加快开发速度。Element UI,这个基于 Vue.js 的组件库,提供了大量界面组件,极大地提升了前端开发的效率。本文将指导您如何开始使用 Element UI 组件库,…...
JavaScript 事件循环(EventLoop) —— 浏览器 Node
一、事件循环的本质 本质:运行时对 JS 脚本的调度方式就叫做事件循环. 对于 浏览器 而言,需要考虑用户交互、UI渲染、脚本运行、网络请求等操作,这些操作必然都依赖于事件去执行,因此,为了协调事件必须要使用事件循环…...
【ROS2】订阅手柄数据,发布运动命令
1、相关消息 sensor_msgs::msg::Joy:用来描述手柄控制器数据 geometry_msgs::msg::Twist :用来描述物体运动时的线速度和角速度 参见博客: 【ROS2】geometry_msgs::msg::Twist和sensor_msgs::msg::Joy 2、订阅和发布 2.1 定义、创建订阅者和发布者 订阅手柄的按键、摇杆…...
WinX86内核02-驱动程序
把昨天的程序改用 c++ 编译,改成 .cpp ,发现编译报错 原因是名称粉碎,因此可以直接 extern “C”声明一下这个函数 或者用 头文件(推荐) 因为 在头文件中 可以把 头文件一起包含进去 #pragma once extern "C" { #include <Ntddk.h> /*驱动入口函…...
基于SpringBoot+Vue的体育馆场地预约系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
【WebGIS】Cesium:天地图加载
天地图是中国国家基础地理信息系统,由中国测绘地理信息局和国家地理信息公共服务平台共同开发和运营。它提供多项地理信息服务,包括地图数据、地理编码、路径规划以及地理搜索等。天地图的目标是为各行业提供高质量、全面的地理信息数据和解决方案。 天…...
[产品管理-46]:产品组合管理中的项目平衡与管道平衡的区别
目录 一、项目平衡 1.1 概述 1.2 项目的类型 1、根据创新程度和开发方式分类 2、根据产品开发和市场周期分类 3、根据风险程度分类 4、根据市场特征分类 5、根据产品生命周期分类 1.3 产品类型的其他分类 1、按物理形态分类 2、按功能或用途分类 3、按技术或创新程…...
【MySQL】MySQL的简单了解详解SQL分类数据库的操纵方法
一、mysql定义 mysql是数据库服务的客户端,mysqld是数据库服务的服务器端。mysql的本质就是基于CS模式下的一种网络服务。数据库一般指的是在磁盘中或内存中存储的特定结构组织的数据,将来就是在磁盘上存储的一套数据库方案。 创建数据库,本质…...
【Python爬虫实战】正则:从基础字符匹配到复杂文本处理的全面指南
🌈个人主页:https://blog.csdn.net/2401_86688088?typeblog 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、正则表达式 (一)正则表达式的基本作用 …...
10.18Python基础迭代器生成器_函数式编程
Python迭代器与生成器 1. 迭代器 Iterator 什么是迭代器 迭代器是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器可以重复使用,而不会像列表那样在迭代时被修改。 迭代器函数iter和next 函数说明iter(iterable)从可迭代对象中返回一个迭…...
HttpPost 类(构建 HTTP POST 请求)
HttpPost 类是 Apache HttpClient 库中的一个类,用于构建 HTTP POST 请求。以下是 HttpPost 类的一些常用方法和代码案例: 常用方法 构造方法: HttpPost(String uri):创建一个 HttpPost 对象,并将请求的 URI 作为参数…...
突破云盘限速壁垒:开源直链解析工具的全场景应用方案
突破云盘限速壁垒:开源直链解析工具的全场景应用方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云…...
Git 高级技巧:Rebase, Stash, Submodule
Git 高级技巧:Rebase, Stash, Submodule 在团队协作开发中,Git 是版本控制的核心工具,但许多开发者仅熟悉基础的 commit、push 和 pull 操作。掌握高级技巧如 Rebase、Stash 和 Submodule,能显著提升代码管理效率。本文将深入解析…...
vLLM-v0.11.0并发优化:max-num-seqs设置,支持高并发请求
vLLM-v0.11.0并发优化:max-num-seqs设置,支持高并发请求 1. 为什么需要关注并发性能? 在大模型推理服务中,并发能力直接决定了系统的吞吐量和响应速度。想象一下,当你的模型服务突然收到100个并发请求时,…...
智能公式+自动处理,SpreadJS AI 插件开启表格数据计算及处理新时代
在技术领域,我们常常被那些闪耀的、可见的成果所吸引。今天,这个焦点无疑是大语言模型技术。它们的流畅对话、惊人的创造力,让我们得以一窥未来的轮廓。然而,作为在企业一线构建、部署和维护复杂系统的实践者,我们深知…...
Go语言标准库context包在微服务调用链中的传播与超时控制
在微服务架构中,服务间的调用链复杂且频繁,如何高效管理调用上下文与超时控制成为关键挑战。Go语言标准库中的context包为此提供了轻量级解决方案,通过传递请求上下文和超时信号,确保系统在分布式环境下的可靠性和可维护性。本文将…...
如何用Fuel构建类型安全的GraphQL客户端:终极完整指南
如何用Fuel构建类型安全的GraphQL客户端:终极完整指南 【免费下载链接】fuel The easiest HTTP networking library for Kotlin/Android 项目地址: https://gitcode.com/gh_mirrors/fu/fuel Fuel是Kotlin/Android平台上最简单易用的HTTP网络库,它…...
Python flask django框架的医疗问诊拿药系统
目录同行可拿货,招校园代理 ,本人源头供货商功能分析:基于Flask/Django的医疗问诊拿药系统核心模块划分技术实现要点数据安全与合规扩展性设计项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 …...
STM32实战:光敏电阻传感器从原理到智能应用
1. 光敏电阻与STM32的完美邂逅 第一次接触光敏电阻时,我完全被这个小东西迷住了。它就像电子世界的"眼睛",能感知光线的强弱变化。记得当时我用万用表测量它的阻值,看着数值随着手电筒的远近而变化,那种感觉就像发现了新…...
全国人大代表:我国自主创新区块链技术已应用到16个中央部委和27个企业
据央视新闻报道,全国人大代表、北京微芯区块链与边缘计算研究院院长董进表示:我国自主创新的区块链底层技术已应用到16个中央部委和27个中央企业,并在税务、跨境贸易、全球支付等领域取得积极进展。其中,我国每年“跑”在自主区块…...
华硕笔记本散热难题:3步用G-Helper解决风扇失控与性能调优
华硕笔记本散热难题:3步用G-Helper解决风扇失控与性能调优 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix…...
