[SerializeField] private float fov = 45f; // 시야각
[SerializeField] private float radius = 10f; // 반지름
private float alertThreshold; // Threshold가 문턱이라는 뜻
private void Start()
{
animator = GetComponent<Animator>();
// FOV를 라디안으로 변환하고 코사인 값을 계산
alertThreshold = Mathf.Cos(fov * Mathf.Deg2Rad / 2f); // 좌우 fov(시야각)의 절반 -> 나누기 2f
}
private void Update()
{
CheckAlert();
}
private void CheckAlert()
{
int layerMask = LayerMask.GetMask("Aestroid");
var hits = Physics2D.CircleCastAll(transform.position, radius, Vector2.up, 0f, layerMask);
bool needAlert = false;
foreach (var hit in hits)
{
Vector2 directionToTarget = (hit.transform.position - transform.position).normalized;
float cos = Vector2.Dot(directionToTarget, transform.up.normalized);
if (cos >= alertThreshold)
{
needAlert = true; // 더이상 검사안하고 루프 종료
break;
}
}
animator.SetBool(blinking, needAlert);
}
전체코드는 위와 같다. 하나씩 살펴보겠다.
// FOV를 라디안으로 변환하고 코사인 값을 계산
alertThreshold = Mathf.Cos(fov * Mathf.Deg2Rad / 2f); // 좌우 fov(시야각)의 절반 -> 나누기 2f
`fov`는 시야각으로 `45도`로 설정했다.
`Mathf.Deg2Rad`을 곱해서 `라디안`으로 변환했다.
`2f`로 나눠준 이유는 시야각이 45도인데 2로 안나눠주면 왼쪽 45도, 오른쪽 45도로 90도의 시야각을 가지기 때문이다.
왜 `Cos`일까?
시야각을 표현하기 위해서는 내가 바라보고 있는 `transform.up` 벡터와 내 주변에 있는 객체 방향의 벡터, 두 벡터 간의 각도를 내적을 통해 계산하기 위해서다.
두 벡터를 내적했을 때 0이 되면 두 벡터는 직각을 이루고 있는 것이다.
그래서 처음에 시야각 45도의 cos값을 알아두는 것이다.
이제 `CheckAlert()`로 가보겠다.
int layerMask = LayerMask.GetMask("Aestroid");
var hits = Physics2D.CircleCastAll(transform.position, radius, Vector2.up, 0f, layerMask);
레이어마스크는 충돌할 소행성의 레이어로 설정했다.
`Physics2D.CircleCastAll`는 이름에서 알다시피 원형 영역내의 객체를 탐지할 수 있다.
매개변수는 (원형 영역의 시작 위치, 반지름, 원의 영역이 확장되는 방향, 원의 영역 확장의 최대 거리, 충돌 감지할 레이어)이다.
여기서 원의 영역 확장의 최대거리가 `0f`인데 이 의미는 단순히 원 영역 내의 충돌만 감지한다는 것이다.
Vector2 directionToTarget = (hit.transform.position - transform.position).normalized;
A에서 B로 가는 벡터를 구할 때 A-B가 아니라 B-A를 해야한다. 위의 코드는 그 의미이다.
float cos = Vector2.Dot(directionToTarget, transform.up.normalized);
이 코드가 내적계산이다. 두 벡터간의 각도를 구한다.
반응형
'스파르타 게임개발종합반(Unity) > TIL - 본캠프 매일 공부 기록' 카테고리의 다른 글
2024.05.22 TIL - SoundManager로 배경음과 효과음 관리 및 재생하기 (0) | 2024.05.22 |
---|---|
2024.05.21 TIL - UnityAction, UnityEvent, delegate, event 차이 (0) | 2024.05.22 |
2024.05.17 TIL - localRotation, rotation 차이, Quaternion.Slerp, Mathf.Atan2, Mathf.Rad2Deg (0) | 2024.05.18 |
2024.05.16 TIL - 객체지향프로그래밍 특강 정리 (0) | 2024.05.16 |
2024.05.14 TIL - Queue를 활용한 오브젝트 풀(ObjectPool) (0) | 2024.05.14 |
댓글