C#/게임 제작 + TIL
Physics2D.OverlapPoint - 2D 상의 겹침의 정도
Toa_
2025. 4. 2. 15:00
건전 라이크의 게임을 만들면서 몬스터의 이동 구현을 addforce 등의 방식이 아니라 코루틴을 통해 특정 좌표값으로 이동시켜 주는 방식을 사용하다 보니, 벽 방향의 이동을 방지하는 코드를 작성하여도 가끔씩 몬스터가 벽 쪽으로 와서 겹쳐져 버리는 경우가 발생하였다.
이렇게 벽과 겹쳐버리면 몬스터가 발사하는 투사체도 막히게 되며 원하는 수준의 플레이 경험을 제공할 수 없기 때문에, 만약 벽에 갇히게 되는 일이 발생하면, 비상 탈출을 할 수 있도록 코드를 만들어 보았다.
이전 프로젝트 에서는 .Bound 를 사용해서 직사각형만큼의 범위를 기반으로 겹침의 유무를 체크하였으나, 해당 방식은 단순히 조금만 겹쳐도 true를 리턴하기 때문에 굳이 필요없는 상황에서도 호출될 우려가 있었다.
따라서. Bound 방식이 아닌 Physics2D.OverlapPoint를 사용해서 구현해 보았다.
bool IsStuckInWall()// 몬스터가 벽에 끼였는지 확인. (비상 탈출용)
{
if (circleCollider == null) return false;
Vector2 center = circleCollider.bounds.center;
float radius = circleCollider.radius * transform.localScale.x; // 실제 반지름 고려
int wallCount = 0;
// 원 주변을 샘플링해서 Wall과 겹치는 부분 체크
for (int i = 0; i < samplePoints; i++)
{
float angle = (i / (float)samplePoints) * 2 * Mathf.PI;
Vector2 samplePoint = center + new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * radius;
if (Physics2D.OverlapPoint(samplePoint, wallLayerMask))
{
wallCount++;
}
}
// 겹친 비율이 설정값을 넘으면 true 반환
return (wallCount / (float)samplePoints) >= 0.3f;// 30% 이상이면 벽에 끼인 것으로 판단.
}
여기서 samplePoint 만큼 원형 콜라이더의 주변을 샘플링 해서 특정 포인트를 기반으로 비교군과의 겹침 정도를 확인하여 bool 값을 리턴하는 함수를 만들어 보았다.
이번 방식은 삼각 함수와 OverlapPoint 등의 자주 않쓰거나 처음 보는 요소가 많았기 때문에, 여러 해외 사이트에서 정보를 아름아름 모아 만든 코드여서 해당 방식이 필요할 때마다 가져와 쓰고 싶어서 기록하는 용도로 글을 작성하였다.