射击服务
2023年10月31日 2024年1月11日
说明
自定义服务: 对距离最近敌人射击
创建服务类
- | |
---|---|
base | BTService |
Public | |
AI/Services | |
STUFireService |
添加构造函数: 设置名称
public
ShootThemUp: AI/Services/STUFireService.h
1USTUFireService();
ShootThemUp: AI/Services/STUFireService.cpp
1USTUFireService::USTUFireService() 2{ 3 NodeName = "Fire"; 4}
添加属性: 存放敌人信息
protected
ShootThemUp: AI/Services/STUFireService.h
1UPROPERTY(EditAnywhere, BlueprintReadWrite) 2FBlackboardKeySelector EnemyActorKey;
服务逻辑: 实现TickNode
protected
ShootThemUp: AI/Services/STUFireService.h
1virtual void TickNode(UBehaviorTreeComponent &OwnerComp, uint8 *NodeMemory, float DeltaSeconds) override;
不需要检查EnemyActor的设置情况, 上节的Decorator提供检查; 还是推荐一个自给自足的逻辑闭环
ShootThemUp: AI/Services/STUFireService.cpp
1#include "BehaviorTree/BlackboardComponent.h" 2#include "AIController.h" 3#include "Components/STUWeaponComponent.h" 4#include "STUUtils.h" 5 6void USTUFireService::TickNode(UBehaviorTreeComponent &OwnerComp, uint8 *NodeMemory, float DeltaSeconds) 7{ 8 const auto Controller = OwnerComp.GetAIOwner(); 9 const auto Blackboard = OwnerComp.GetBlackboardComponent(); 10 11 const auto HasAim = Blackboard && Blackboard->GetValueAsObject(EnemyActorKey.SelectedKeyName); 12 13 if (Controller) 14 { 15 const auto WeaponComponent = STUUtils::GetSTUPlayerComponent<USTUWeaponComponent>(Controller->GetPawn()); 16 if (WeaponComponent) 17 { 18 HasAim ? WeaponComponent->FireStart() : WeaponComponent->FireStop(); 19 } 20 } 21}
应该在TickNode最后调用基类TickNode
1Super::TickNode(OwnerComp, NodeMemory, DeltaSeconds);
修改武器基类射击逻辑
STUBaseWeapon
NPC的控制器类型为AIController, 控制器相关逻辑需调整
获取子弹轨迹信息: GetTraceData; 调用GetPlayerViewPoint; 被武器派生类的MakeShot调用
APlayerController::GetPlayerViewPoint
AIController不具有类似功能的成员函数
若游戏角色的控制器类型为APlayerController, 走原有逻辑; 自行设置子弹起点和方向向量
ShootThemUp: Weapon/STUBaseWeapon.cpp
1// GetPlayerViewPoint 2 3const auto STUCharacter = Cast<ACharacter>(GetOwner()); 4if (!STUCharacter) return false; 5 6if (STUCharacter->IsPlayerControlled()) 7{ 8 // 原逻辑 9} 10else 11{ 12 ViewLocation = GetMuzzleWorldLocation(); 13 ViewRotation = WeaponMeshComponent->GetSocketRotation(MuzzleSocketName); 14} 15return true;
查看
调整NPC视觉感知参数
BP_STUAIController > STUAIPerceptionComponent
- | |
---|---|
Sight Radius | 2000 |
Lose Sight Radius | 2500 |
PeripheralVisionHalfAngleDegrees | 90 |
设置行为树
BT_STUCharacter
-
为Attack添加射击服务
-
设置射击目标
选中STUFireService
, 设置Details > STUFire Service > Enemy Actor Key
为EnemyActor
总结
- NPC注意到敌人就可以瞄准射击, 这一点太猛了
- 之前为NPC添加了转向过渡动画, 而射击在这之前