六一的部落格


关关难过关关过,前路漫漫亦灿灿。




说明

弹药补给包含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}

弹药补给



说明

弹药补给包含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}