본문 바로가기
유니티/기초

유니티 카메라 이동 및 회전 [기초 5]

by 노튜 2020. 5. 5.
728x90

 

카메라 이동에 관한 글이다. 

 

게임 월드 구현에 있어 카메라는 굉장히 중요한 역할을 한다.

어떻게 구현하냐에 따라 게임이 달라 보일 수 있으며, 사용자의 플레이를 용이하게 도와준다. 

 

카메라 시점은 대표적으로 1인칭과 3인칭을 들 수 있다. 

1인칭은 FPS 게임에서 주로 쓰이며, 3인칭은 아케이드, RPG 게임들에 주로 사용된다. 

 

본 글에서는 기본적이고 간단한 부분만을 언급한다. 

 

  • CameraControl 클래스를 생성하고, Main Camera에 CameraControl 클래스를 등록한다. 
  • 카메라의 이동 및 회전은 대상이 먼저 움직이고 그 후에 전환이 이루어 지도록LateUpdate()에 구현한다. 

1. 추적 카메라 

1.1 추적 카메라 구현

 

다양한 많은 게임들은 카메라가 캐릭터를 따라 이동하도록 구현되어 있다.  

 

offset을 두어 일정한 거리에서 대상을 바라보도록 설정한다. 

offset 변경을 통해 카메라 위치를 조절할 수 있다. 

 

Y와 Z값으로 대상과의 거리를 설정하고, 그 후에 대상을 바라보도록 카메라를 회전시킨다.

 

 

public class CameraControl : MonoBehaviour
{
  public Transform target;
  // 대상을 바라보는 카메라의 위치 
  public Vector3 lookOffset = new Vector3(0, 5.0f, -5.0f);
  
  void LateUpdate()
  {
    // 대상으로부터 offset 만큼 떨어져 있도록 설정
    transform.position = target.position + lookOffset;
    
    // 대상을 보도록 설정
    transform.LookAt(target);
   
  }

}

 

2.2 1인칭과 3인칭 그리고 탑뷰

 

위의 코드는 Y축 5만큼, Z축 -5만틈 떨어진 거리에서 대상을 따라가도록 설정되어 있다. 즉, 3인칭 시점이다.

이를 1인칭 시점으로 변경하는 것은 offset을 0으로 설정하면 가능하다. 

 

하지만 캐릭터가 바라보는 대상과 시야가 다르게 된다. 

캐릭터의 하위 오브젝트로 Empty gameobject를 생성하고 이를 바라보는 대상으로 지정하면 된다.

Empty Gameobject를 캐릭터의 눈과 일치하도록 위치시킨다.

 

물론, 위의 코드 없이 카메라를 캐릭터의 차일드 오브젝트로 두고, 카메라를 눈의 위치에 두어도 1인칭 시점이 가능하다.       

 

미니맵처럼 대상의 머리위에서 바라보게 하는 것은 0, Y, 0의 Y 값만 가진 offset을 설정하면 가능하다. 

 

2. 카메라 Zoom in and out

 

 근거리 및 원거리에서 물체를 바라보도록 구현하는 경우가 있다. 

 카메라 줌 인 아웃 기능을 구현하여 보자. 

 

Input.GetAxis("Mouse ScrollWheel")은 마우스 휠 입력 값이다.

 

Mathf.Clamp(A, Min, Max)은 A를 최소와 최대 사이의 값을 갖도록 한다. 

 ex)  0 < A < 10 

0보다 작으면 0의 값을, 10보다 크면 10의 값을 반환한다. 

 

대상과 카메라 사이의 거리는 offset에 현재 Zoom level을 곱한 값이다.

이는 현재 대상을 바라보는 카메라의 각도는 그대로 유지한채, 가깝거나 먼 거리에서 바라보도록

설정하게 된다.

 

public class CameraControl : MonoBehaviour
{
  public Transform target;
  public Vector3 offset = new vector3(0, 1.0f, -1.0f)
  
  public float currentZoom = 7.0f;
  
  public float minZoom = 5.0f;
  public float maxZoom = 10.0f;

 void Update()
 {
  // 마우스 휠로 줌 인아웃
  currentZoom -= Input.GetAxis("Mouse ScrollWheel");
  // 줌 최소 및 최대 설정 
  currentZoom = Mathf.Clamp(currentZoom, minZoom, maxZoom);
 
 }
 
 void LateUpdate()
 {
 // 변경된 카메라 위치 적용
  transform.position = target.position + offset * currentZoom;
  transform.LookAt(target);
 }

}

 

3. 카메라 회전 

 

카메라를 바라보는 대상을 기준으로 회전시키는 것은 transform의 RotateAround()를 이용하면 쉽게 구현이 가능하다. 

 

Transform.RotateAround(대상, 회전축, 회전 각도)을 나타낸다.

 

회전각도에 + 값을 설정하면, 대상의 왼쪽에서 카메라를 바라보도록 회전 시키고, - 값을 설정하면, 오른쪽에서 바라보도록 회전 시킨다. 

transform.RotateAround(target, Axis, Angle)

 

4. 추적 및 카메라 각도 회전 

 "q" 버튼을 누르게 되면, 왼쪽으로 회전하고, "e"를 누르면 오른쪽으로 회전하도록 구현하였다. 

 회전된 값을 기반으로 offset을 재설정하여, 이를 최종적으로 반영한다.  

 

public class CameraControl : MonoBehaviour
{
  public Transform target;
  public Vector3 offset = new vector3(0, 1.0f, -1.0f)
  
  public float currentZoom = 7.0f;
  
  float minZoom = 5.0f;
  float maxZoom = 10.0f;

 void Update()
 {
 
   if (Input.GetKey("q"))
   {
     // rotate toward left Yaxis
     transform.RotateAround(target.position, Vector3.up, 5.0f);

     offset = transform.position - target.position;
     offset.Normalize();
    }
    if (Input.GetKey("e"))
    {
      transform.RotateAround(target.position, Vector3.up, -5.0f);

      offset = transform.position - target.position;
      offset.Normalize();
     }
     
  // 마우스 휠로 줌 인아웃
  currentZoom -= Input.GetAxis("Mouse ScrollWheel");
  // 줌 최소 및 최대 설정 
  currentZoom = Mathf.Clamp(currentZoom, minZoom, maxZoom);
 
 }
 
 void LateUpdate()
 {
 // 변경된 카메라 위치 적용
  transform.position = target.position + offset * currentZoom;
  transform.LookAt(target);
 }

}

※ 위의 코드 기능은 정상적이다. 그러나 한가지 정확히 표현되지 않은 부분이 존재한다.  

 

 

 

참고

 

https://catlikecoding.com/unity/tutorials/movement/orbit-camera/

 

Orbit Camera

A Unity Movement tutorial about controlling a sphere via an orbit camera.

catlikecoding.com

 

728x90