유니티(Unity) 프로그래밍

Unity 카메라

게임첫걸음 2024. 9. 29. 22:14

 GTA5, 오버워치, 발로란트 등 1인칭, 3인칭 게임을 플레이해보면 정면 시야를 제공받고 마우스를 바꿔가며 플레이해보셨을 겁니다. 여기엔 렌더링이라는 과정을 거치는데 먼저 정의에 대해 설명드리겠습니다. 렌더링은 3D Scene에서 객체를 화면에 표시하는 과정입니다. 이 과정은 6개의 단계의 작업을 포함합니다.

  1. 객체의 위치와 상태 결정
  2. 카메라의 시야
  3. 조명 계산
  4. 쉐이딩
  5. 텍스처 사용
  6. 최종 출력

위의 계산과 과정은 게임 엔진에서 기본적으로 다뤄주기 때문에 세세하게 다루진 않겠지만, 나중에 많은 오브젝트들을 다루는 복잡한 게임을 만들땐 위의 과정들을 훑어보시는 걸 추천드립니다. 오늘은 렌더링과 카메라의 상관관게를 설명할 겁니다.

오버워치 1인칭 게임

 위의 그림에서 빨간원과 상자는 렌더링되지 않은 오브젝트들이고 초록색 원, 상자는 렌더링되어 시야에 보이는 오브젝트들입니다. 절두체(Frustum)란 카메라의 시야를 정의하는 '구조' 로, 카메라가 보는 시간적 영역을 나타내고 3가지 요소로 구성됩니다.

  • 시점(Fied Of View): 카메라가 포착할 수 있는 각도. 일반적으로 렌즈의 각도와 관련이 있습니다.
  • 가까운 평면(Near Plane): 카메라에서 가장 가까운 거리의 평면, 이 평면보다 가벼운 오브젝트들은 렌더링되지 않습니다.
  • 먼 평면(Far Plane): 카메라에서 가장 먼 거리의 평면, 이 평면보다 먼 물체 또한 렌더링되지 않습니다.

 게임을 할 때마다 구성되어있는 모든 게임 오브젝트들을 렌더링해버리면 많은 비용이 발생하여 컴퓨터에 부화가 올 수 있습니다. 이러한 부분을 해결하기 위한 방법이 바로 이것입니다. GTA가 만약 모든 오브젝트를 렌더링한다면 여러분들의 컴퓨터는 실행하자마자 쿨러가 최고속력으로 돌다가 문제가 발생할 것입니다. 이제 스크립트를 통해 우리가 마우스를 대는 곳에 3차원 위치값 적용할 수 있는 코드를 살펴보겠습니다.

private void Update()
{
    if(Input.GetMouseButtonDown(0))
    {
        Vector3 mousePosToWorld = GetMousePositionToWorld();

        Vector3 dir = GetDirectionCameraToCursor();
    }
}

private Vector3 GetMousePositionToWorld()
{
    Vector3 mousePos = Input.mousePosition;
    mousePos.z = Camera.main.nearClipPlane; //z값 아무거나 특정안해주면 0, 0, -10에 고정되어있음.
    Vector3 screenToWorld = Camera.main.ScreenToWorldPoint(mousePos);

    return screenToWorld;
}

public Vector3 GetDirectionCameraToCursor()
{
    return (GetMousePositionToWorld() - Camera.main.transform.position).normalized;
}
  • GetMousePositionToWorld(); : 마우스의 위치값을 월드 지정하는 함수입니다.
  • GetDirectionCameraToCursor(); : 카메라 위치와 커서 위치 간의 방향 벡터를 계산하는 기능의 함수로 카메라의 시점에서 커서가 있는 위치를 향한 방향을 나타냅니다.
  • Input.GetMouseButtonDown( )) : 마우스 좌클릭 시
  • Camera.main.nearClipPlane; : mouse의 z위치값을 위에서 설명한 카메라 절두체 개념의 가까운 평면(Near Plane)으로 지정한다는 뜻입니다. 
  • Camera.main.ScreenToWorldPoint(mousePos) : 설정된 화면 좌표를 기준으로 월드 좌표로 변환합니다.
  • Camera.main.transform.position: 카메라의 월드 위치를 가져옵니다.
  • 두 위치의 차이를 계산하여 카메라와 커서까지의 거리에 대한 방향 벡터를 구하기 위해 - (빼기 연산)해줍니다.
  • normalized; :뺀 방향 벡터를 정규화하여 길이가 1인 벡터를 반환합니다. 

'유니티(Unity) 프로그래밍' 카테고리의 다른 글

UI Canvas  (0) 2024.10.21
코루틴 (Coroutine)을 통한 Picking  (5) 2024.10.03
Unity Prefabs과 Stack, Queue  (1) 2024.09.26
Unity Collider(Trigger, Collision)  (2) 2024.09.24
Unity 충돌감지  (1) 2024.09.20