1. BTService를 부모로하는 BTService_Detect 클래스를 생성
- 행동패턴은 플레이어를 발견했는지, 못했는지에 따라 추격과 정찰로 구분한다. 셀렉터로 확장한다.
- 추격과 정찰 중 추격에 더 우선권을 주고, 추격로직은 Target을 행헤 이동하도록 설계한다
- TickNode 함수에는 NPC의 위치를 기준으로 반경 6미터 내에 캐릭터가 있는지 감지하는 기능을 넣는다.
반경 내에 모든 캐릭터를 감지하는 OverlapMultiByChannel 함수를 사용한다. - 감지된 모든 캐릭터 정보는 목록을 관리하는 데 적합한 TArry로 전달된다.
2. 오브젝트 채널 및 트레이스 채널 설정
캐릭터에서 Trace을 블록으로 해줘야, Trace로 콜리전 체크를 할떄, 판단을 할수가 있다.
Trace 콜리전 체크를 할떄 사용할 ECC_GameTraceChannel2
3. 코드
//h
UCLASS()
class KGAME_API UBTService_Detect : public UBTService
{
GENERATED_BODY()
public:
UBTService_Detect();
protected:
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
};
//cpp
#include "BTService_Detect.h"
#include "KAIController.h"
#include "KCharacter.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "DrawDebugHelpers.h"
UBTService_Detect::UBTService_Detect()
{
NodeName = TEXT("K_Detect");
}
void UBTService_Detect::TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)
{
Super::TickNode(OwnerComp, NodeMemory, DeltaSeconds);
APawn* ControllingPawn = OwnerComp.GetAIOwner()->GetPawn();
if (nullptr == ControllingPawn) return;
UWorld* World = ControllingPawn->GetWorld();
FVector Center = ControllingPawn->GetActorLocation();
float DetectRadius = 600.0f;
TArray<FOverlapResult> OverlapResults;
FCollisionQueryParams CollisionQueryParam(NAME_None, false, ControllingPawn);
bool bResult = World->OverlapMultiByChannel(
OverlapResults,
Center,
FQuat::Identity,
ECollisionChannel::ECC_GameTraceChannel2,
FCollisionShape::MakeSphere(DetectRadius),
CollisionQueryParam
);
if (bResult)
{
for (auto OverlapResult : OverlapResults)
{
AKCharacter* targetCharacter = Cast<AKCharacter>(OverlapResult.GetActor());
if (targetCharacter && targetCharacter->GetController()->IsPlayerController())
{
OwnerComp.GetBlackboardComponent()->SetValueAsObject(AKAIController::TargetKey, targetCharacter);
DrawDebugSphere(World, Center, DetectRadius, 16, FColor::Green, false, 0.2f);
DrawDebugPoint(World, targetCharacter->GetActorLocation(), 10.0f, FColor::Blue, false, 0.2f);
DrawDebugLine(World, ControllingPawn->GetActorLocation(), targetCharacter->GetActorLocation(), FColor::Blue, false, 0.27f);
return;
}
}
}
else
{
OwnerComp.GetBlackboardComponent()->SetValueAsObject(AKAIController::TargetKey, nullptr);
}
//DrawDebugSphere(World, Center, DetectRadius, 16, FColor::Red, false, 0.2f);
}
4. 행동트리 수정
- 이제 서비스가 실행된 결과에 따라 셀렉터 데코레이더 왼쪽의 추격과 셀렉터 데코레이터 오른쪽의 정찰 로직이 나눠지도록 행동트리 로직을 구성한다
- 서비스 결과는 블랙보드의 Target 키에 값이 있는지, 없는지로 구분할 수 있다.
- 데코레이터 노드를 사용한다.
- 해당 키값의 변경이 감지되면 현재 컴포짓 노드의 실행을 곧바로 취소하고 노티파이 옵저버 값알
OnValue Change로 변경한다.
'Unreal > Game 2 ' 카테고리의 다른 글
10.3 AI 공격 (0) | 2019.07.05 |
---|---|
10.1 AI 정찰 (0) | 2019.07.02 |
10. AI 만들기 (0) | 2019.07.01 |
9.3 PlayerState - 작성 중 (0) | 2019.06.30 |
9.2 플레이어 HUD (0) | 2019.06.30 |