NPC自行更换武器
2023年11月1日 2024年1月11日
说明
AI Weapon Component
当前武器子弹耗尽时, 更换为仍有弹药的武器
查看当前NPC更换武器需求
-
调整武器顺序: 第一个为发射器
BP_STUAICharacter > WeaponComponent
拖动Index[1]到最上 -
修改发射器默认子弹数
BP_STULauncherWeapon > Details > Default Ammo
设置Clips = 2, Bullets = 1 -
修改步枪弹药库和伤害
BP_STURifleWeapon > Details
Default Ammo
取消勾选Infinite
, 设置Clips = 3- 设置DamageAmount = 0.0
查看: 射击完发射器榴弹后, 停止射击
NPC射击榴弹特效异常
在枪口处爆炸, 无移动
调试思路
NPC和玩家游戏角色的区别, 刚好在上节子弹轨迹的修改; 上层控制器类型
- GetPlayerViewPoint由
GetTraceData
调用: 能获取到ViewLocation和ViewRotation值 - 发射器MakeShot调用GetTraceData后, 调用
MakeHit
打印碰撞信息: 永远发生碰撞; 怀疑MuzzleSocket变换
输出碰撞点: 和枪口位置一致
将轨迹终点改为根据射程计算得到的终点: 轨迹和射击方向近乎垂直
原因
MuzzleSocket变换配置存在失误; 已在 武器 > 榴弹类
更正
创建C++类
- | |
---|---|
基类 | STUWeaponComponent |
路径 | Components |
Public | |
类名 | STUAIWeaponComponent |
调整武器基类接口的访问属性
ShootThemUp: Weapon/STUBaseWeapon.h
IsAmmoEmpty: protected > public
调整武器组件成员的访问属性
ShootThemUp: Components/STUWeaponComponent.h
- 之前误把FireStart和FireStop声明成虚函数: 恢复FireStop
1void FireStop();
- STUAIWeaponComponent需要重新实现下列接口逻辑
1virtual void FireStart(); 2virtual void NextWeapon();
- 派生类需要访问下列成员
private > protected
- Weapons数组
- 当前武器指针CurrentWeapon
- 当前武器在数组中的索引CurrentWeaponIndex
- Weapons数组
- 派生类需要使用下列成员函数
private > protected
- CanFire和CanEquip
- EquipWeapon
- CanFire和CanEquip
实现STUAIWeaponComponent
覆写虚函数
public
ShootThemUp: Components/STUAIWeaponComponent.h
1virtual void FireStart() override; 2virtual void NextWeapon() override;
射击时, 若当前武器没有弹药, 尝试更换武器
ShootThemUp: Components/STUAIWeaponComponent.cpp
1#include "Weapon/STUBaseWeapon.h" 2 3void USTUAIWeaponComponent::FireStart() 4{ 5 if (!CanFire()) return; 6 7 if (CurrentWeapon->IsAmmoEmpty()) 8 { 9 NextWeapon(); 10 } 11 else 12 { 13 CurrentWeapon->FireStart(); 14 } 15}
若存在武器弹药不为空, 切换到该武器
ShootThemUp: Components/STUAIWeaponComponent.cpp
1void USTUAIWeaponComponent::NextWeapon() 2{ 3 if (!CanEquip()) return; 4 5 int32 NextIndex = (CurrentWeaponIndex + 1) % Weapons.Num(); 6 while (NextIndex != CurrentWeaponIndex) 7 { 8 if (!Weapons[NextIndex]->IsAmmoEmpty()) break; 9 NextIndex = (NextIndex + 1) % Weapons.Num(); 10 } 11 12 if (NextIndex != CurrentWeaponIndex) 13 { 14 CurrentWeaponIndex = NextIndex; 15 EquipWeapon(CurrentWeaponIndex); 16 } 17}
AICharacter使用STUAIWeaponComponent
参考STUBaseCharacter使用STUCharacterMovementComponent
ShootThemUp: Player/STUBaseCharacter.cpp
ShootThemUp: AI/STUAICharacter.cpp
1#include "Components/STUAIWeaponComponent.h" 2 3ASTUAICharacter::ASTUAICharacter(const FObjectInitializer &ObjInit) 4 : Super(ObjInit.SetDefaultSubobjectClass<USTUAIWeaponComponent>("WeaponComponent")) 5{ 6 // ... 7}
查看
榴弹用完后自动更换武器, 步枪子弹用完后无法射击