当前位置: 首页 > news >正文

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.创建界面&#xff0c;根据笔记23的界面中添加 2.绑定界面控件 UPROPERTY(meta (Bindwidget))UTextBlock* WeaponAmmoAmount;UPROPERTY(meta (Bindwidget))UTextBlock* CarriedAmmoAmount; 3.添加武器类型枚举 3.1创建武器类型枚举头文件 3.2创建文…...

限制游客在wordpress某分类下阅读文章的数量

在WordPress中实现某个分类下的内容限制游客只能阅读前5篇文章&#xff0c;注册用户可以阅读更多文章的功能&#xff0c;可以通过以下步骤来完成&#xff1a; 1. 安装和激活插件 首先&#xff0c;你可以使用一个插件来简化这个过程。一个常用的插件是 “MemberPress” 或 “R…...

Oracle云主机申请和使用教程:从注册到SSH连接的全过程

今天我要和大家分享如何成功申请Oracle云主机,并进行基本的配置和使用。我知道很多同行的朋友在申请Oracle云主机时都遇到了困难&#xff08;疑惑abc错误&#xff09;,可能试了很多次都没有成功。现总结一下这些年来的一些注册流程经验&#xff0c;或许你们也能成功申请到自己的…...

芯知识 | NVH-FLASH语音芯片支持平台做语音—打造音频IC技术革新

随着科技的飞速发展&#xff0c;人们对于电子产品的音频性能要求越来越高。在这种背景下&#xff0c;NVH-FLASH系列语音芯片应运而生&#xff0c;作为音频IC领域的一次重大技术革新&#xff0c;NVH-FLASH系列语音芯片凭借其卓越的性能与灵活的支持平台&#xff0c;正逐步引领着…...

机器学习——解释性AI与可解释性机器学习

解释性AI与可解释性机器学习: 理解机器学习模型背后的逻辑 随着人工智能技术的广泛应用&#xff0c;机器学习模型越来越多地被用于决策过程。然而&#xff0c;这些模型&#xff0c;尤其是深度学习模型&#xff0c;通常被视为“黑箱”&#xff0c;难以理解其背后的决策逻辑。解…...

中国全国省市区县汇总全国省市区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&#xff08;无类别域间路由&#xff09; 目的IP & 当前路由器的子网掩码 …...

路由器原理和静态路由配置

一、路由器的工作原理 根据路由表转发数据 接收数据包→查看目的地址→与路由表进行匹配找到转发端口→转发到该端口 二、路由表的形成 它是路由器中维护的路由条目的集合&#xff0c;路由器根据路由表做路径选择&#xff0c;里面记录了网段ip地址和对应下一跳接口的接口号。…...

UE5 使用Animation Budget Allocator优化角色动画性能

Animation Budget Allocator是UE内置插件&#xff0c;通过锁定动画系统所占CPU的预算&#xff0c;在到达预算计算量时对动画进行限制与优化。 开启Animation Budget Allocator需要让蒙皮Mesh使用特定的组件&#xff0c;并进行一些编辑器设置即可开启。 1.开启Animation Budget…...

Element UI 组件库详解:从入门到精通

在追求统一且流畅的用户体验时&#xff0c;开发者们常常选择使用 UI 组件库来加快开发速度。Element UI&#xff0c;这个基于 Vue.js 的组件库&#xff0c;提供了大量界面组件&#xff0c;极大地提升了前端开发的效率。本文将指导您如何开始使用 Element UI 组件库&#xff0c;…...

JavaScript 事件循环(EventLoop) —— 浏览器 Node

一、事件循环的本质 本质&#xff1a;运行时对 JS 脚本的调度方式就叫做事件循环. 对于 浏览器 而言&#xff0c;需要考虑用户交互、UI渲染、脚本运行、网络请求等操作&#xff0c;这些操作必然都依赖于事件去执行&#xff0c;因此&#xff0c;为了协调事件必须要使用事件循环…...

【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的体育馆场地预约系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

【WebGIS】Cesium:天地图加载

天地图是中国国家基础地理信息系统&#xff0c;由中国测绘地理信息局和国家地理信息公共服务平台共同开发和运营。它提供多项地理信息服务&#xff0c;包括地图数据、地理编码、路径规划以及地理搜索等。天地图的目标是为各行业提供高质量、全面的地理信息数据和解决方案。 天…...

[产品管理-46]:产品组合管理中的项目平衡与管道平衡的区别

目录 一、项目平衡 1.1 概述 1.2 项目的类型 1、根据创新程度和开发方式分类 2、根据产品开发和市场周期分类 3、根据风险程度分类 4、根据市场特征分类 5、根据产品生命周期分类 1.3 产品类型的其他分类 1、按物理形态分类 2、按功能或用途分类 3、按技术或创新程…...

【MySQL】MySQL的简单了解详解SQL分类数据库的操纵方法

一、mysql定义 mysql是数据库服务的客户端&#xff0c;mysqld是数据库服务的服务器端。mysql的本质就是基于CS模式下的一种网络服务。数据库一般指的是在磁盘中或内存中存储的特定结构组织的数据&#xff0c;将来就是在磁盘上存储的一套数据库方案。 创建数据库&#xff0c;本质…...

【Python爬虫实战】正则:从基础字符匹配到复杂文本处理的全面指南

&#x1f308;个人主页&#xff1a;https://blog.csdn.net/2401_86688088?typeblog &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、正则表达式 &#xff08;一&#xff09;正则表达式的基本作用 &#xf…...

10.18Python基础迭代器生成器_函数式编程

Python迭代器与生成器 1. 迭代器 Iterator 什么是迭代器 迭代器是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器可以重复使用&#xff0c;而不会像列表那样在迭代时被修改。 迭代器函数iter和next 函数说明iter(iterable)从可迭代对象中返回一个迭…...

HttpPost 类(构建 HTTP POST 请求)

HttpPost 类是 Apache HttpClient 库中的一个类&#xff0c;用于构建 HTTP POST 请求。以下是 HttpPost 类的一些常用方法和代码案例&#xff1a; 常用方法 构造方法&#xff1a; HttpPost(String uri)&#xff1a;创建一个 HttpPost 对象&#xff0c;并将请求的 URI 作为参数…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...