본문 바로가기

게임프로그래밍/실습2

[실습2] 57. 블랙보드 키 만들고 가장 가까이 있는 원하는 액터 설정하기

1. 블랙보드 키

 

블랙보드 키는 행동 트리 내에서 데이터를 저장하고 관리할 수 있는 변수를 말한다. 이것을 통해 가장 가까이 있는 플레이어를 저장할 수 있다.


 

2. 서비스에서 블랙보드 키 추가하기

 

서비스에 블랙보드 키를 추가하여 이것을 행동트리의 블랙보드 키와 연동시킬 것이다. 서비스 클래스로 들어가자.

 

 

이렇게 블랙보드 키 변수를 추가할 수 있다.

 

눈 모양 아이콘을 선택하여 이를 노출시키도록 하자.

 

행동트리에서 확인하면 이렇게 키가 노출되는 것을 볼 수 있다.

 

 

디테일 패널에도 이렇게 나타나는 것을 볼 수 있는데 이것을 통해 블랙보드 키를 실제로 할당하는 것이 가능해진다.

 

위의 키는 테스트용으로 만든 것이기 때문에 삭제해 주자.

 

이제 실제로 블랙보드 키를 만들어 볼 것이다.


3. 블랙보드에 키 추가하기

 

 

블랙보드에 들어가면 키를 추가할 수 있다. 블랙보드 키에 플레이어를 저장할 것이고 그러기 위해서는 오브젝트 타입으로 설정해야할 것이다.

 

 

디테일 패널에서 액터의 종류를 더 상세히 설정할 수도 있다.

 

Instance Synced 해당 설정은 해당 키를 해당 블랙보드를 가지고 있는 모든 객체가 공유할 것인지 설정하는 것이다.

 

즉 한 에너미 클래스에서 블랙보드 키로 액터를 선택하면 모든 에너미가 같은 액터를 설정하게 된다. 이렇게 하면 당연히 안되기 때문에 해제한 그대로 놔두도록 하자.

 

 

추가로 float 타입 키도 만들어주었다.

 


4. 서비스와 행동트리의 블랙보드 키 연결하기.

 

이제 이 블랙보드 키를 서비스에서 설정하는 방법을 알아보자.

 

액터를 블랙보드 키에 저장할 것인데 이때 모든 액터를 저장하고 그렇기 때문에 이것이 플레이어인지 아닌지 구분할 필요가 있다. 이는 액터 태그를 통해 구분할 것이다. 에너미와 플레이어 각자의 블루프린트로 들어가 태그를 설정하도록 하자.

 

 

이런 식으로 설정하면 된다.

 

물론 이는 C++에서도 설정이 가능하다.

 

이제 실제로 가장 가까운 플레이어를 찾는 방법을 알아보자.

 

서비스 클래스에서 변수를 추가해준다.

 

이 셀렉터들은 행동트리에서 값을 할당해 줄 것이다. 이와 함께 Name 변수도 추가해주었다.

 

 

이제 컨트롤 폰이 무엇인지에 따라 타겟의 태그를 설정해준다.

 

플레이어와 아군인 AI를 위해 설정한 것인데 이를 구현할 생각이 없다면 굳이 하지 않아도 되는 작업이다.

 

위의 과정을 콜렙스 하고 이제 액터를 찾을 것이다.

 

태그를 통해 모든 액터를 불러와 이 중 타겟 태그를 가지고 있는 액터만 찾는다.

 

이제 이 액터와 컨트롤 폰의 위치를 계산해서 가장 가까이에 있는 타겟을 찾으면 될 것이다.


5. 가장 가까이에 있는 액터 찾기

 

이제 가장 가까이에 있는 액터를 찾는 법을 알아보자. 한가지 놀라운(?) 사실은 이 기능은 이미 엔진에 존재하기 때문에 굳이 블루프린트든 C++에서든 구현할 필요가 없다.

 

 

이렇게 하면 가장 가까이 있는 액터를 찾을 수 있다.

 

다만 이 코드는 코딩 테스트나 기타 면접등에서 나오기 정말 좋은 코드이기 때문에 원리를 아는 것이 좋다고 한다.

AActor* UGameplayStatics::FindNearestActor(FVector Origin, const TArray<AActor*>& ActorsToCheck, float& Distance)
{
	AActor* NearestActor = nullptr;
	float DistanceFromNearestActor = Distance = TNumericLimits<float>::Max();

	for (AActor* ActorToCheck : ActorsToCheck)
	{
		if (ActorToCheck)
		{
			const float DistanceFromActorToCheck = (Origin - ActorToCheck->GetActorLocation()).SizeSquared();
			if (DistanceFromActorToCheck < DistanceFromNearestActor)
			{
				NearestActor = ActorToCheck;
				DistanceFromNearestActor = DistanceFromActorToCheck;
			}
		}
	}

	if (NearestActor)
	{
		Distance = FMath::Sqrt(DistanceFromNearestActor);
	}

	return NearestActor;
}

 

자세한 내용은 챗GPT에 물어보면 알려주는데 간단히 요약하면 오리진과 액터의 거리를 계산하는데 이때 SizeSquared() 를 통해 거리를 제곱으로 비교하여 불필요한 백터의 제곱근 연산을 방지하여 최적화를 하는 방식이다.

 

정확한 거리가 아닌 단순히 비교를 위해 거리를 구하는 것이라 불필요한 연산을 막아야 한다.

 

이제 가까운 액터를 알아냈으니 이를 블랙보드 키에 저장하면 된다.

 

블랙보드 키를 이렇게 설정할 수 있다. 액터를 저장하는 것이니 여기서는 오브젝트를 선택해야 할 것이다.

 

 

이렇게 셀렉터와 연결해주면 된다.

 

마찬가지로 거리로 설정해주면 된다.

 

이제 행동 트리로 돌아가 연결해주도록 하자.

 

 

디테일 패널에서 설정해주면 된다.

 

이렇게 해서 행동트리에서 가장 가까운 액터를 찾을 수 있게 구현하였다.