Unity

시야 범위에 타켓 오브젝트가 들어와 있는지 확인하는 방법

코샵 2023. 11. 21. 11:58
반응형

Unity 오브젝트의 시야 범위에 타켓 오브젝트가 들어와 있는지 확인하는 방법은 여러 가지가 있습니다.

그 중 하나인 두 오브젝트의 내적을 구하고, 라디안(π)을 호도각(0~360°)으로 변환시켜 사용하는 방법을 소개하겠습니다.

 

내적이란?

내적은 두 벡터의 크기와 방향의 일치 정도를 나타내는 값으로 Vector3.Dot() 메서드를 통해 구할 수 있습니다.

A⋅B=AB⋅cos(θ) 여기서 ∣A B 각각 벡터 A B 크기(길이)이고,

θ A B 사이의 각입니다. 내적의 결과는 스칼라값입니다.

public static float Dot(Vector3 lhs, Vector3 rhs) => (float) ((double) lhs.x * (double) rhs.x + (double) lhs.y * (double) rhs.y + (double) lhs.z * (double) rhs.z);

 

이 함수는 두 벡터의 내적을 계산하여 float 값으로 반환합니다.

 

세타각이란?

세타각은 두 벡터의 방향 사이의 각도입니다. 세타각은 다음과 같이 구할 수 있습니다.

Math.Acos((double) f)

이 함수는 주어진 실수 f의 아크코사인 값을 계산하여 float 값으로 반환합니다.

내적에서 계산된 cos(θ)에서 θ를 계산하기 위해 Acos을 계산합니다.

θ=cos1(dot(a,b)ab)\theta = \cos^{-1}\left(\frac{\text{dot}(\mathbf{a}, \mathbf{b})}{\|\mathbf{a}\| \cdot \|\mathbf{b}\|}\right)

 

Rad2Deg란?

public struct Mathf
{
	public const float Rad2Deg = 57.29578f;
}

라디안 값을 단위로 변환하는 상수입니다. 라디안은 원의 반지름에 대한 호의 길이가 반지름과 같은 크기인 각을 나타내는 각도의 단위입니다. 

 

시야 범위 확인

다음은 시야 범위에 타켓 오브젝트가 들어와 있는지 확인하는 예제 코드입니다.

// 오브젝트의 시야 방향을 나타내는 벡터를 생성합니다.
Vector3 viewDirection = transform.forward;

// 타켓 오브젝트의 위치와 오브젝트의 위치를 이용하여 두 벡터를 생성합니다.
Vector3 targetPosition = target.transform.position;
Vector3 originPosition = transform.position;

// 두 벡터의 내적을 계산합니다.
float dot = Vector3.Dot(viewDirection, targetPosition - originPosition);

// 내적 값을 사용하여 라디안을 구하고, 호도각으로 변환합니다.
float theta = Mathf.Acos(dot) * Mathf.Rad2Deg;

// 세타각이 시야 범위 내에 있는지 확인합니다.
if (theta < fov)
{
    // 시야 범위에 있습니다.
}

이 코드에서 fov는 시야 범위의 각도를 나타내는 상수입니다.

 

결론

Vector3.Dot() 함수를 사용하여 내적을 구하고, Mathf.Acos() 함수와 Mathf.Rad2Deg를 사용하여 세타각을 구하는 방법은 오브젝트의 시야 범위에 타켓 오브젝트가 들어와 있는지 확인할 수 있는 방법입니다.