내일배움캠프 76일차 TIL
오늘도 오전에 기술면접 예상질문을 풀어보고 팀 프로젝트 개발을 진행했다.
객체를 이동할 때 벡터를 정규화(Nomarlized) 하는 이유에 대해 설명해주세요.
벡터를 정규화하는 가장 큰 이유는 이동속도를 균일하게 유지하기 위해서이다. 벡터를 정규화하면 방향은 유지되고 크기가 1인 단위벡터가 되는데, 이는 우리가 객체를 벡터의 크기와 상관없이 균일한 속도로 이동하고 싶을 때 큰 도움이 된다. 그 외에도 벡터를 정규화하여 물리연산에 사용하면 크기를 고려할 필요가 없으므로 성능 향상에 긍정적인 영향을 끼친다.
월드 스페이스(World Space)와 로컬 스페이스(Local Space)의 차이에 대해 설명해주세요.
월드 스페이스는 게임이나 3D 환경의 전체적인, 절대적인 좌표 시스템을 의미한다. 이 공간에서는 월드 전체에 영향을 미치는 라이트나 환경 효과를 적용할 때 유용하다.
로컬 스페이스는 객체나 모델 자체의 좌표 시스템을 의미한다. 이 공간에서의 좌표는 객체의 부모나 자체적인 참조 시스템에 대한 상대적인 위치를 나타내며, 객체의 자식 요소들은 부모의 로컬 스페이스를 기준으로 위치한다.
팀 프로젝트 개발 - 트러블 슈팅
플레이어가 콜라이더 사이에 끼이는 현상
어제 해당 현상을 Composite Collider를 활용하여 해결했었다. 하지만 강제적인 Rigidbody 사용으로 인한 성능 저하와, 이전보다 빈도수는 확실히 적어졌으나 여전히 지형 콜라이더 속으로 플레이어가 들어가버리는 현상이 남아있었다. 들어갈 틈이 없는데 대체 어떻게 들어간 것일까? 자료를 찾아보고 튜터님께도 문의해본 결과 문제의 원인은 유니티가 물리 연산을 처리하는 과정에 있었다. 유니티에서 처리하는 물리 연산은 우리가 기본적으로 생각하는 것처럼 연속적으로 이루어지는 것이 아니라, 일정한 주기를 가지고 마치 스탑모션을 그리는 것처럼 순간 순간의 값을 계산하며 이를 화면에 보여주는 것이다. 즉 하필 물체가 콜라이더에 부딛혀야 하는 순간이 그 검사와 검사 사이에 일어날 예정이었다면, 부딛히는 과정이 생략되고 콜라이더 너머로 물체가 넘어갔을 수도 있는 것이다. 이는 충돌이 빠르게 일어날수록 잘 일어나는 현상이다. 이 문제를 해결할 수 있는 방법은 크게 두 가지가 있었다.
- 물리 연산 검사 주기 자체를 줄인다.
- Raycast를 사용하여 플레이어가 지형 콜라이더에 빠른 속도로 충돌하기 전에 감지하여 넘어가지 않도록 처리를 한다.
첫번째 방법이 구현하기는 쉬우나 성능 저하의 우려가 있어 두번째 방법을 사용하기로 했다.
Raycast
Raycast는 유니티에서 제공하는 Physics클래스에 있는 메서드이다. 레이저를 쏴서 해당 방향에 물체가 있는지 여부와, 물체가 있다면 해당 물체에 대한 정보 등을 얻을 수 있는 유용한 기능이다. 생각보다 무거운 연산이라서 주기가 짧은 반복문에 사용하기는 조심스러웠고, 플레이어의 속도가 일정값을 넘어가면 Raycast를 사용하는 방식으로 구현해보았다.
if(Mathf.Abs(Rigidbody.velocity.magnitude) > _maxSpeed * 3f)
{
int layerMask = 1 << 16;
RaycastHit2D hit = Physics2D.Raycast(transform.position, Rigidbody.velocity.normalized, 1f, layerMask);
Rigidbody.velocity = hit.collider != null ? Vector2.zero : Rigidbody.velocity;
if(hit.collider != null)
{
Debug.DrawRay(transform.position, hit.point, Color.yellow, 5f);
Debug.Log(hit.collider.name);
}
}