弹药补给
2023年10月11日 2024年1月11日
说明
弹药补给包含2个参数: 武器类型和弹匣数
弹药补给逻辑
添加属性
ShootThemUp: Pickups/STUAmmoPickup.h
protected
1class ASTUBaseWeapon; 2 3UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ClampMin = "1.0", ClampMax = "10.0")) 4int32 ClipsAmount = 10; 5 6UPROPERTY(EditAnywhere, BlueprintReadWrite) 7TSubclassOf<ASTUBaseWeapon> WeaponType;
添加接口: 若非死亡跌倒或组件不可寻, 调用武器组件接口
ShootThemUp: Pickups/STUAmmoPickup.cpp
1#include "Components/STUHealthComponent.h" 2#include "Components/STUWeaponComponent.h" 3#include "GameFramework/Pawn.h" 4#include "STUUtils.h" 5 6// GivePickupTo 7 8const auto HealthComponent = STUUtils::GetSTUPlayerComponent<USTUHealthComponent>(PlayerPawn); 9if (!HealthComponent || HealthComponent->IsDead()) return false; 10 11const auto WeaponComponent = STUUtils::GetSTUPlayerComponent<USTUWeaponComponent>(PlayerPawn); 12if (!WeaponComponent) return false; 13 14return WeaponComponent->TryToAddAmmo(WeaponType, ClipsAmount);
武器组件逻辑
添加接口: 调用对应类型武器接口
ShootThemUp: Components/STUWeaponComponent.h
public
1bool TryToAddAmmo(TSubclassOf<ASTUBaseWeapon> WeaponType, int32 ClipsAmount);
ShootThemUp: Components/STUWeaponComponent.cpp
1bool USTUWeaponComponent::TryToAddAmmo(TSubclassOf<ASTUBaseWeapon> WeaponType, int32 ClipsAmount) 2{ 3 for (const auto Weapon : Weapons) 4 { 5 if (Weapon && Weapon->IsA(WeaponType)) 6 { 7 return Weapon->TryToAddAmmo(ClipsAmount); 8 } 9 } 10 return false; 11}
武器逻辑
ShootThemUp: Weapon/STUBaseWeapon.h
1// public 2bool TryToAddAmmo(int32 ClipsAmount); 3 4// protected 5bool IsAmmoFull() const;
ShootThemUp: Weapon/STUBaseWeapon.cpp
1bool ASTUBaseWeapon::IsAmmoFull() const 2{ 3 return CurrentAmmo.Clips == DefaultAmmo.Clips && // 4 CurrentAmmo.Bullets == DefaultAmmo.Bullets; 5} 6 7bool ASTUBaseWeapon::TryToAddAmmo(int32 ClipsAmount) 8{ 9 if (CurrentAmmo.Infinite || IsAmmoFull() || ClipsAmount <= 0) return false; 10 11 if (IsAmmoEmpty()) 12 { 13 UE_LOG(LogBaseWeapon, Display, TEXT("Ammo was empty!")); 14 CurrentAmmo.Clips = FMath::Clamp(CurrentAmmo.Clips + ClipsAmount, 0, DefaultAmmo.Clips + 1); 15 OnClipEmpty.Broadcast(); 16 } 17 else if (CurrentAmmo.Clips < DefaultAmmo.Clips) 18 { 19 if (CurrentAmmo.Clips + ClipsAmount <= DefaultAmmo.Clips) 20 { 21 CurrentAmmo.Clips += ClipsAmount; 22 UE_LOG(LogBaseWeapon, Display, TEXT("Clips were added")); 23 } 24 else 25 { 26 CurrentAmmo.Clips = DefaultAmmo.Clips; 27 CurrentAmmo.Bullets = DefaultAmmo.Bullets; 28 UE_LOG(LogBaseWeapon, Display, TEXT("Ammo is full now")); 29 } 30 } 31 else 32 { 33 CurrentAmmo.Bullets = DefaultAmmo.Bullets; 34 UE_LOG(LogBaseWeapon, Display, TEXT("Bullets were added")); 35 } 36 return true; 37}
查看
-
将榴弹弹匣可以容纳的榴弹数改为2
BP_STULauncherWeapon
-
设置弹药补给的武器类型为
BP_STULauncherWeapon
BP_STUAmmoPickup
初始状态, 无法拾取弹药补给
射击一次后, 提示榴弹增加
打掉一个弹匣后, 提示弹药装满
打空后, 提示弹药为空
再次打空后, 切换武器, 拾取弹药装备, 切换回发射器, 弹药信息显示不正确
解决问题
装弹时, 只对当前武器进行操作
委托定义中, 增加一个传参
ShootThemUp: STUCoreTypes.h
1class ASTUBaseWeapon; 2 3DECLARE_MULTICAST_DELEGATE_OneParam(FOnClipEmptySignature, ASTUBaseWeapon*);
修改调用
ShootThemUp: Weapon/STUBaseWeapon.cpp
1// DecreaseAmmo 2OnClipEmpty.Broadcast(this); 3 4// TryToAddAmmo 5OnClipEmpty.Broadcast(this);
修改声明和定义
ShootThemUp: Components/STUWeaponComponent.h
1void OnEmptyClip(ASTUBaseWeapon *AmmoEmptyWeapon);
ShootThemUp: Components/STUWeaponComponent.cpp
1void USTUWeaponComponent::OnEmptyClip(ASTUBaseWeapon *AmmoEmptyWeapon) 2{ 3 if (!AmmoEmptyWeapon) return; 4 5 if (CurrentWeapon == AmmoEmptyWeapon) 6 { 7 ChangeClip(); 8 } 9 else 10 { 11 for (const auto Weapon : Weapons) 12 { 13 if (Weapon == AmmoEmptyWeapon) 14 { 15 Weapon->ChangeClip(); 16 } 17 } 18 } 19}