이제 단일 지점으로의 Patrol은 가능한 것을 볼 수 있다. 이제 한 Patrol Point에서 다른 Patrol Point로 이동할 수 있도록 구현해보자.

이를 위해 타켓포인트를 여러개 만들어주고 배열에 할당해주자

 

그리고 Tick함수에서 Target과의 거리를 측정해주는 함수가 작동할 수 있도록 Actor와의 지정해준 거리에 따라 bool값을 반환해주는 새로운 함수를 만들어주자.

Enemy.cpp

bool AEnemy::InTargetRange(AActor* Target, double Radius)
{
	const double DistanceToTarget = (Target->GetActorLocation() - GetActorLocation()).Size();
	return DistanceToTarget <= Radius;
}

 

이를 바탕으로  Tick함수에서 HealthBar 조건문도 변경해주고 PatrolTarget조건문도 만들어주자.

이때 PatrolRadius(멈출 거리)를 지정해주어야하는데 이 값이 double인데 moveTo에서는 이 반경보다 조금 더 이동하기 때문에 조금 더 거리를 지정해주어야한다.

Enemy.h

	UPROPERTY(EditAnywhere)
	double PatrolRadius = 200.f;

Enemy.cpp

void AEnemy::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (CombatTarget)
	{
		if (!InTargetRange(CombatTarget,CombatRadius))
		{
			CombatTarget = nullptr;
			if (HealthBarWidget)
			{
				HealthBarWidget->SetVisibility(false);
				Attributes->SetHealth(100.f);
			}
		}
	}

	if (PatrolTarget && EnemyController)
	{
		TArray<AActor*> ValidTargets;
		for (AActor* Target : PatrolTargets)
		{
			if (Target != PatrolTarget)
			{
				ValidTargets.AddUnique(Target);
			}
		}


		if (InTargetRange(PatrolTarget, PatrolRadius))
		{
			const int32 TargetSelection = FMath::RandRange(0, ValidTargets.Num() - 1);
			PatrolTarget = ValidTargets[TargetSelection];
			
			FAIMoveRequest MoveRequest;
			MoveRequest.SetGoalActor(PatrolTarget);
			//도착이라고 생각할 거리
			MoveRequest.SetAcceptanceRadius(15.f);
			EnemyController->MoveTo(MoveRequest);
		}
	}
}

 

이렇게 해주고 실행해주면 랜덤한 순찰포인트로 순찰하는 것을 볼 수 있다.

+ Recent posts