六一的部落格


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




概览

  • 在武器类所属源文件中定义数据结构, 存放弹药数据
  • 在武器类中添加数据结构, 保存弹药规格和数据
  • 使用武器时, 更新弹药库存, 无存货停止射击
  • 无弹药时, 关闭步枪连续射击定时器

定义弹药数据结构体

两种使用场景: 当前弹药数据; 弹药规格 / 初始值

Infinite配置
步枪 true
榴弹发射器 false

步枪

当前弹药数据 弹药规格 / 初始值
Bullets 弹夹中的子弹数 弹夹中的子弹上限
Infinite 无限模式
Clips 只在Infinite为false时使用; 弹夹或个数

榴弹发射器

当前弹药数据
Bullets -
Infinite 无限模式
Clips 只在Infinite为false时使用; 弹药个数

定义结构体

ShootThemUp: Weapon/STUBaseWeapon.h

 1USTRUCT(BlueprintType)
 2struct FAmmoData
 3{
 4    GENERATED_USTRUCT_BODY()
 5
 6    UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
 7    int32 Bullets;
 8
 9    UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
10    bool Infinite;
11
12    UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (EditConditon = (!Infinite)))
13    int32 Clips;
14};

添加数据成员

-
DefaultAmmo 弹药规格 / 初始值
CurrentAmmo 当前弹药数据

ShootThemUp: Weapon/STUBaseWeapon.h

1// protected
2UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)       
3FAmmoData DefaultAmmo {15, 10, false};
4
5// private
6FAmmoData CurrentAmmo;

设置弹药初始值

ShootThemUp: Weapon/STUBaseWeapon.cpp

1// BeginPlay
2CurrentAmmo = DefaultAmmo;

使用武器时, 更新弹药库存, 无存货停止射击


添加接口: 弹夹是否为空

ShootThemUp: Weapon/STUBaseWeapon.cpp

1bool ASTUBaseWeapon::IsClipEmpty() const
2{
3    return CurrentAmmo.Bullets == 0;
4}

添加接口: 更换弹夹

ShootThemUp: Weapon/STUBaseWeapon.cpp

1void ASTUBaseWeapon::ChangeClip()
2{
3    CurrentAmmo.Bullets = DefaultAmmo.Bullets;
4    if (!CurrentAmmo.Infinite)
5    {
6        --CurrentAmmo.Clips;
7    }
8    UE_LOG(LogBaseWeapon, Display, TEXT("---------Change Clip----------"));
9}

添加接口: 是否还有弹药

ShootThemUp: Weapon/STUBaseWeapon.cpp

1bool ASTUBaseWeapon::IsAmmoEmpty() const
2{
3    return CurrentAmmo.Infinite ? false : (!CurrentAmmo.Bullets && !CurrentAmmo.Clips);
4}

添加接口: 输出弹药信息

目前没有UI, 在终端输入信息

ShootThemUp: Weapon/STUBaseWeapon.cpp

1void ASTUBaseWeapon::LogAmmo()
2{
3    FString AmmoInfo = "Ammo: " + FString::FromInt(CurrentAmmo.Bullets) + " / ";
4    AmmoInfo += CurrentAmmo.Infinite ? "Infinite" : FString::FromInt(CurrentAmmo.Clips);
5    UE_LOG(LogBaseWeapon, Display, TEXT("%s"), *AmmoInfo);
6}

添加接口: 更新弹药库存

ShootThemUp: Weapon/STUBaseWeapon.cpp

1void ASTUBaseWeapon::DecreaseAmmo()
2{
3    --CurrentAmmo.Bullets;
4    LogAmmo();
5    if (IsClipEmpty() && !IsAmmoEmpty())
6    {
7        ChangeClip();
8    }
9}

添加声明

protected

ShootThemUp: Weapon/STUBaseWeapon.h

1bool IsClipEmpty() const;
2void ChangeClip();
3bool IsAmmoEmpty() const;
4void LogAmmo();
5void DecreaseAmmo();

射击时判断弹药库存, 更新弹药数据

  • 步枪

    ShootThemUp: Weapon/STURifleWeapon.cpp
    1// MakeShot
    2
    3if (IsAmmoEmpty()) return;
    4
    5DecreaseAmmo();
  • 榴弹发射器

    ShootThemUp: Weapon/STULauncherWeapon.cpp
    1// MakeShot
    2
    3if (IsAmmoEmpty()) return;
    4
    5DecreaseAmmo();

查看

  1. 设置步枪和榴弹发射器的初始弹药

    DefaultAmmo Infinite Bullets Clips
    BP_STULauncherWeapon false 1 5
    BP_STURifleWeapon true 15 10
  2. 日志

    • 步枪能不停换弹夹(可以把Clips初始值设为0)
    • 榴弹发射器可以射击6次: 已装载弹夹和剩余弹夹



步枪连续射击定时器问题

ShootThemUp: Weapon/STURifleWeapon.cpp

弹药结束时关闭定时器

1// MakeShot
2
3if (IsAmmoEmpty())
4{
5    FireStop();
6    return;
7}

弹药数据



概览

  • 在武器类所属源文件中定义数据结构, 存放弹药数据
  • 在武器类中添加数据结构, 保存弹药规格和数据
  • 使用武器时, 更新弹药库存, 无存货停止射击
  • 无弹药时, 关闭步枪连续射击定时器

定义弹药数据结构体

两种使用场景: 当前弹药数据; 弹药规格 / 初始值

Infinite配置
步枪 true
榴弹发射器 false

步枪

当前弹药数据 弹药规格 / 初始值
Bullets 弹夹中的子弹数 弹夹中的子弹上限
Infinite 无限模式
Clips 只在Infinite为false时使用; 弹夹或个数

榴弹发射器

当前弹药数据
Bullets -
Infinite 无限模式
Clips 只在Infinite为false时使用; 弹药个数

定义结构体

ShootThemUp: Weapon/STUBaseWeapon.h

 1USTRUCT(BlueprintType)
 2struct FAmmoData
 3{
 4    GENERATED_USTRUCT_BODY()
 5
 6    UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
 7    int32 Bullets;
 8
 9    UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
10    bool Infinite;
11
12    UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (EditConditon = (!Infinite)))
13    int32 Clips;
14};

添加数据成员

-
DefaultAmmo 弹药规格 / 初始值
CurrentAmmo 当前弹药数据

ShootThemUp: Weapon/STUBaseWeapon.h

1// protected
2UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)       
3FAmmoData DefaultAmmo {15, 10, false};
4
5// private
6FAmmoData CurrentAmmo;

设置弹药初始值

ShootThemUp: Weapon/STUBaseWeapon.cpp

1// BeginPlay
2CurrentAmmo = DefaultAmmo;

使用武器时, 更新弹药库存, 无存货停止射击


添加接口: 弹夹是否为空

ShootThemUp: Weapon/STUBaseWeapon.cpp

1bool ASTUBaseWeapon::IsClipEmpty() const
2{
3    return CurrentAmmo.Bullets == 0;
4}

添加接口: 更换弹夹

ShootThemUp: Weapon/STUBaseWeapon.cpp

1void ASTUBaseWeapon::ChangeClip()
2{
3    CurrentAmmo.Bullets = DefaultAmmo.Bullets;
4    if (!CurrentAmmo.Infinite)
5    {
6        --CurrentAmmo.Clips;
7    }
8    UE_LOG(LogBaseWeapon, Display, TEXT("---------Change Clip----------"));
9}

添加接口: 是否还有弹药

ShootThemUp: Weapon/STUBaseWeapon.cpp

1bool ASTUBaseWeapon::IsAmmoEmpty() const
2{
3    return CurrentAmmo.Infinite ? false : (!CurrentAmmo.Bullets && !CurrentAmmo.Clips);
4}

添加接口: 输出弹药信息

目前没有UI, 在终端输入信息

ShootThemUp: Weapon/STUBaseWeapon.cpp

1void ASTUBaseWeapon::LogAmmo()
2{
3    FString AmmoInfo = "Ammo: " + FString::FromInt(CurrentAmmo.Bullets) + " / ";
4    AmmoInfo += CurrentAmmo.Infinite ? "Infinite" : FString::FromInt(CurrentAmmo.Clips);
5    UE_LOG(LogBaseWeapon, Display, TEXT("%s"), *AmmoInfo);
6}

添加接口: 更新弹药库存

ShootThemUp: Weapon/STUBaseWeapon.cpp

1void ASTUBaseWeapon::DecreaseAmmo()
2{
3    --CurrentAmmo.Bullets;
4    LogAmmo();
5    if (IsClipEmpty() && !IsAmmoEmpty())
6    {
7        ChangeClip();
8    }
9}

添加声明

protected

ShootThemUp: Weapon/STUBaseWeapon.h

1bool IsClipEmpty() const;
2void ChangeClip();
3bool IsAmmoEmpty() const;
4void LogAmmo();
5void DecreaseAmmo();

射击时判断弹药库存, 更新弹药数据

  • 步枪

    ShootThemUp: Weapon/STURifleWeapon.cpp
    1// MakeShot
    2
    3if (IsAmmoEmpty()) return;
    4
    5DecreaseAmmo();
  • 榴弹发射器

    ShootThemUp: Weapon/STULauncherWeapon.cpp
    1// MakeShot
    2
    3if (IsAmmoEmpty()) return;
    4
    5DecreaseAmmo();

查看

  1. 设置步枪和榴弹发射器的初始弹药

    DefaultAmmo Infinite Bullets Clips
    BP_STULauncherWeapon false 1 5
    BP_STURifleWeapon true 15 10
  2. 日志

    • 步枪能不停换弹夹(可以把Clips初始值设为0)
    • 榴弹发射器可以射击6次: 已装载弹夹和剩余弹夹



步枪连续射击定时器问题

ShootThemUp: Weapon/STURifleWeapon.cpp

弹药结束时关闭定时器

1// MakeShot
2
3if (IsAmmoEmpty())
4{
5    FireStop();
6    return;
7}