본문 바로가기
포트폴리오 제작/Project_P

Project_P 행동트리 모델 공격방향으로 로테이션

by k99812 2024. 12. 18.

 

기존 공격 노드는 공격시 방향전환을 하지않아 플레이어가 사거리내에서 움직이면 계속 처음 공격방향으로 공격을 진행

 

심플 페러렐 노드를 사용하여 어택과 Turn노드를 동시에 실행

 

UBTTask_TurnToTarget


헤더파일

#include "CoreMinimal.h"
#include "BehaviorTree/BTTaskNode.h"
#include "BTTask_TurnToTarget.generated.h"

/**
 * 
 */
UCLASS()
class PROJECT_P_API UBTTask_TurnToTarget : public UBTTaskNode
{
	GENERATED_BODY()
	
public:
	UBTTask_TurnToTarget();

	virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
};

 

생성자와 노드 실행 함수 ExecuteTask를 상속받음

 

생성자

UBTTask_TurnToTarget::UBTTask_TurnToTarget()
{
	NodeName = TEXT("TurnToTarget");
}

 

생성자에서 노드이름을 지정

 

ExecuteTask

EBTNodeResult::Type UBTTask_TurnToTarget::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
	EBTNodeResult::Type Result = Super::ExecuteTask(OwnerComp, NodeMemory);

	APawn* ControllingPawn = OwnerComp.GetAIOwner()->GetPawn();
	if (!IsValid(ControllingPawn))
	{
		return EBTNodeResult::Failed;
	}

	APawn* TargetPawn = Cast<APawn>(OwnerComp.GetBlackboardComponent()->GetValueAsObject(BBKEY_TARGET));
	if (!IsValid(TargetPawn))
	{
		return EBTNodeResult::Failed;
	}

	UAbilitySystemComponent* ASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(ControllingPawn);
	if (!IsValid(ASC))
	{
		return EBTNodeResult::Failed;
	}

	const UPPGruntAttributeSet* AttributeSet = ASC->GetSet<UPPGruntAttributeSet>();
	if (!IsValid(AttributeSet))
	{
		return EBTNodeResult::Failed;
	}

	float TurnSpeed = AttributeSet->GetAITurnSpeed();
	FVector LookVector = TargetPawn->GetActorLocation() - ControllingPawn->GetActorLocation();
	LookVector.Z = 0.0f;
	FRotator TargetRot = FRotationMatrix::MakeFromX(LookVector).Rotator();
	ControllingPawn->SetActorRotation(FMath::RInterpTo(ControllingPawn->GetActorRotation(), TargetRot, GetWorld()->GetDeltaSeconds(), TurnSpeed));

	return Result;
}

 

  • EBTNodeResult::Type Result = Super::ExecuteTask(OwnerComp, NodeMemory);
    • 부모함수를 실행하여 결과 저장
  • APawn* ControllingPawn = OwnerComp.GetAIOwner()->GetPawn();
    • OwnerComp변수를 활용해 AI컨트롤러가 조종하고있는 몬스터를 가져옴
  • APawn* TargetPawn = Cast<APawn>(OwnerComp.GetBlackboardComponent()->GetValueAsObject(BBKEY_TARGET));
    • 블랙보드에서 타겟을 가져옴
  • UAbilitySystemComponent* ASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(ControllingPawn);
    • 어트리뷰트셋을 가져오기 위해 ASC를 가져옴
  • const UPPGruntAttributeSet* AttributeSet = ASC->GetSet<UPPGruntAttributeSet>();
    • 어트리뷰셋을 가져옴
  • float TurnSpeed = AttributeSet->GetAITurnSpeed();
    • 어트리뷰트셋을 이용하여 몬스터의 회전속도를 가져옴
  • FVector LookVector = TargetPawn->GetActorLocation() - ControllingPawn->GetActorLocation();
    • 회전시킬 백터를 구하기 위해 Vector(타겟위치) - Vector(몬스터)로 바로볼 백터를 구함
  • LookVector.Z = 0.0f;
    • 회전과 관련없는 Z축을 0로 만듦
  • FRotator TargetRot = FRotationMatrix::MakeFromX(LookVector).Rotator();
    • MakeFromX 함수를 통해 X축을 LooKVector로 회전하기위한 로테이터를 구함
  • ControllingPawn->SetActorRotation
    (FMath::RInterpTo(ControllingPawn->GetActorRotation(), TargetRot, GetWorld()->GetDeltaSeconds(), TurnSpeed));
    • SetActorRotation함수로 몬스터 로테이션을 변경
    • RInterpTo함수로 부드럽게 회전
    • RInterpTo(현재로테이션, 변경할로테이션, 델타타임, 턴스피드)