EDR_Project / CanAttack (1) BTS_EDR_AbleAttack

24.11.23 공격 사거리 수정 사항 입니다.

기존에 IsInAttackRange 데코레이터에서는 원래 실시간으로 범위 안에있으면 true를 반환해줘야하는데 공격 범위안에 들어와도 감지를 못하는 문제가 있었습니다.

디버깅을 해본 결과 실시간이 아닌 실행된 순간의 위치에서 범위를 체크하고 있는 것 같아 틱 함수로 블랙보드 변수에 실시간으로 넘겨주기 위해 비헤이비어트리 서비스로 새로 만들게 되었습니다.

 

BTS_EDR_AbleAttack.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "BehaviorTree/BTService.h"
#include "BTS_EDR_AbleAttack.generated.h"

/**
 * 
 */
UCLASS()
class EDR_API UBTS_EDR_AbleAttack : public UBTService
{
	GENERATED_BODY()
public:

	UBTS_EDR_AbleAttack();

protected:
	virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)override;
	bool AbleAttack = false;
};
반응형

BTS_EDR_AbleAttack.cpp

// Fill out your copyright notice in the Description page of Project Settings.
#include "BTS_EDR_AbleAttack.h"
#include "Enemy_EDR_AIController.h"
#include "MyCharacter.h"
#include "DrawDebugHelpers.h"
#include "EDR/YS/EDRCharacter.h"
#include "BehaviorTree/BlackboardComponent.h"

UBTS_EDR_AbleAttack::UBTS_EDR_AbleAttack()
{

}
void UBTS_EDR_AbleAttack::TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)
{
	Super::TickNode(OwnerComp, NodeMemory, DeltaSeconds);
	// AIContorller가 제어하는 폰을 가져옴
	auto ControllingPawn = OwnerComp.GetAIOwner()->GetPawn();
	if (nullptr == ControllingPawn)
	{
		return;
	}

	UWorld* World = ControllingPawn->GetWorld();
	FVector Center = ControllingPawn->GetActorLocation();
	if (nullptr == World)
	{
		return;
	}	
	// 블랙보드의 Target 플레이어 캐스팅
	auto Target = Cast<AEDRCharacter>(OwnerComp.GetBlackboardComponent()->GetValueAsObject(AEnemy_EDR_AIController::TargetKey));
	if (nullptr == Target)
	{
		GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Red, TEXT("over"));
		return;
	}

	// 거리 조건 계산
	float Range = 500.0f;
	// 사거리 안에 들어오면 true
	AbleAttack = Target->GetDistanceTo(ControllingPawn) <= Range;
	OwnerComp.GetBlackboardComponent()->SetValueAsBool(AEnemy_EDR_AIController::AbleAttack, AbleAttack);
	
	// 사거리 디버깅 스피어
	if (AbleAttack)
	{
		// 탐지할경우
		DrawDebugSphere(World, Center, 400.0f, 16, FColor::Blue, false, 0.2f);
	}
	else
	{
		//탐지 못한경우
		DrawDebugSphere(World, Center, 400.0f, 16, FColor::Red, false, 0.2f);
	}
	
}

 

실시간으로 판정하기 위해 틱 함수 안에서 Target( 플레이어 캐릭터의 실시간 위치 ) 와 현재 AIContoller가 조종하는 캐릭터( 보스 캐릭터 )와의 거리의 차이가 정해둔 Range( 사거리 ) 보다 작거나 같을 경우 AbleAttacktrue가 되고 블랙보드 변수로 넘겨줍니다.

 

디버깅으로 사거리 안에있으면 파란색 스피어 사거리 밖이면 빨간색 스피어를 출력합니다.

 

실행 화면

공격 사거리 밖에 있을 때

 

공격 사거리 안에 있을 때