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

+ Recent posts