Monster 클래스에 SplineComponent가 있음
Monster 클래스에 TargetLocation, PatrolIndex를 갱신하고 있음
// 가져온 PatrolIndex를 바탕으로 SplinePoint의 GetLocation을 통해 TargetLocation 반환
FVector AMonster::GetPatrolLocation(int32 Index) const
{
if (!PatrolSpline || PatrolSpline->GetNumberOfSplinePoints() == 0) return GetActorLocation();
// Get SplinePoint to World Location
FVector Location = PatrolSpline->GetLocationAtSplinePoint(Index, ESplineCoordinateSpace::World);
return Location;
}
// PatrolIndex를 호출할 때마다 1씩 증가시키고 계속 순환하는 방식 PatrolIndex를 갱신하여 반환한다.
int32 AMonster::GetNextPatrolIndex(int32 CurrentIndex) const
{
CurrentIndex = (CurrentIndex + 1) % PatrolSpline->GetNumberOfSplinePoints();// Cycle
LOG(TEXT("PatrolIndex increment : %d", CurrentIndex));
return CurrentIndex;
}
도착하면 TriggerMovementFinished()가 호출되도록 BlueprintCallable 함수를 만듦.
TriggerMovementFinished()가 호출되면 델리게이트가 호출
BTTask_CustomMove의 ExecuteTask에서 델리게이트 바인딩
ExecuteTask에서 EBTNode::Result 를 InProgress로 반환
Destination에 도착하면 바인딩 했던 함수 (HandleMoveFinished) 호출 되면서 FinishLetentTask 호출
그러면서 OnTaskFinished 가 자동 호출되면서 바인딩이 해제
#include "Monster/BT/BTTask_CustomMove.h"
#include "AIController.h"
#include "Monster/FlyingAIPathfindingBase.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "AbyssDiverUnderWorld.h"
UBTTask_CustomMove::UBTTask_CustomMove()
{
NodeName = "Custom Move To Location";
bNotifyTick = false;
bNotifyTaskFinished = true; // Ensuring OnTaskFinished execution
}
EBTNodeResult::Type UBTTask_CustomMove::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
CashedOwnerComp = &OwnerComp;
AAIController* AIController = OwnerComp.GetAIOwner();
if (!AIController) return EBTNodeResult::Failed;
APawn* AIPawn = AIController->GetPawn();
if (!AIPawn) return EBTNodeResult::Failed;
CashedPathComp = AIPawn->FindComponentByClass<UFlyingAIPathfindingBase>();
if (!CashedPathComp) return EBTNodeResult::Failed;
UBlackboardComponent* BlackboardComp = OwnerComp.GetBlackboardComponent();
if (!BlackboardComp) return EBTNodeResult::Failed;
FVector TargetLocation = BlackboardComp->GetValueAsVector("TargetLocation");
// Arrived Event Binding
CashedPathComp->OnFinishedMoving.AddDynamic(this, &UBTTask_CustomMove::HandleMoveFinishied);
if (AIPawn->HasAuthority())
{
CashedPathComp->S_MoveTo(TargetLocation);
}
else
{
LOG(TEXT("Tried to call Server_MoveTo on client"));
}
return EBTNodeResult::InProgress;
}
void UBTTask_CustomMove::OnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTNodeResult::Type TaskResult)
{
if (CashedPathComp)
{
CashedPathComp->OnFinishedMoving.RemoveDynamic(this, &UBTTask_CustomMove::HandleMoveFinishied);
}
}
void UBTTask_CustomMove::HandleMoveFinishied()
{
if (CashedOwnerComp)
{
FinishLatentTask(*CashedOwnerComp, EBTNodeResult::Succeeded);
}
}
BTTask_FindNextPatrolLocation 에서 SetValueAsVector(TargetLocation)에 들어가는 TargetLocation 값 확인
BlackboardComp->SetValueAsVector(TargetLocationKey.SelectedKeyName, TargetLocation);
BlackboardComp->SetValueAsInt(PatrolIndexKey.SelectedKeyName, Monster->GetNextPatrolIndex(Index));
LOG(TEXT("TargetLocation : %s"), *TargetLocation.ToString())
에디터를 켜서 확인한 결과 정확하게 값은 들고옴.
Blackboard key 값도 정확하게 들고와서 Set 하고있음
아오 뭐가 문제지 ㅅㅂ..???
와 그냥 중력적용되어있어서 이동이 안되었던 거임….
Character Component의 gravityScale을 0으로하니깐 말끔하게 해결