본문 바로가기
코딩과 알고리즘

유니티3D 플레이어 조작 #4. 3인칭 플레이어 뷰!

지난 시간에서는 카메라가 플레이어를 따라다니는 예제를 살펴보았지요.

itadventure.tistory.com/397

 

유니티3D 플레이어 조작 #3. 카메라 팔로우 미!

드라마나 영화를 보면 카메라가 주연이나 조연을 향해 카메라를 클로즈업할 때가 있습니다. 사실 그 이유는..  :  : '시청률'을 올리기 위해서지요 :) 아무래도 필요한 순간에 필요한 인물에게

itadventure.tistory.com

플레이어의 움직임에 화면이 마치 동기화되듯이 카메라가 수평 이동을 하는 것을 볼 수 있었는데요.

요새 게임이나 가상세계 컨텐츠들은 이러한 방식보다는 플레이어의 뒷모습을 바라보며
뒤에서 플레이어의  매력적인 행보(?)를 지켜보는 경우가 많습니다.

이번 시간에는 3인칭 시점에서 플레이어를 지켜보며 관점의 카메라에 대해 다루어 보도록 하겠습니다.

먼저 CamController 스크립트를 더블클릭, 비주얼 스튜디오를 열어주신 다음에,

아래 스크립트로 내용을 변경해 주세요.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CamController : MonoBehaviour
{
    public GameObject player; // 바라볼 플레이어 오브젝트입니다.
    public float xmove = 0;  // X축 누적 이동량
    public float ymove = 0;  // Y축 누적 이동량
    public float distance = 3;

    // Update is called once per frame
    void Update()
    {
        xmove += Input.GetAxis("Mouse X"); // 마우스의 좌우 이동량을 xmove 에 누적합니다.
        ymove -= Input.GetAxis("Mouse Y"); // 마우스의 상하 이동량을 ymove 에 누적합니다.
        transform.rotation = Quaternion.Euler(ymove, xmove, 0); // 이동량에 따라 카메라의 바라보는 방향을 조정합니다.
        Vector3 reverseDistance = new Vector3(0.0f, 0.0f, distance); // 카메라가 바라보는 앞방향은 Z 축입니다. 이동량에 따른 Z 축방향의 벡터를 구합니다.
        transform.position = player.transform.position - transform.rotation * reverseDistance; // 플레이어의 위치에서 카메라가 바라보는 방향에 벡터값을 적용한 상대 좌표를 차감합니다.
    }
}

그리고 플레이해보시면 아래와 같이 카메라가 플레이어 바로 뒤를 비추는 것을 볼 수 있는데요.

마우스를 움직이면 플레이어를 중심으로 화면이 빙글 돌게 되는 것을 보실 수 있습니다.
플레이어가 마치 주인공이 된 것 같지요.

마우스를 좌우로 이동하면 좌우로 화면이 빙그르르 회전하고
마우스를 위아래로 움직이면 마치 하늘에서 내려다보는 듯한 화면도 가능합니다.
보통은 마우스 위아래 이동에 따른 카메라 이동량에는 제한을 두게 마련이지만, 이 스크립트는 제한이 없기 때문에
이러한 물구나무 서기와 같은 연출도 가능하지요.

핵심 부분을 잠깐 설명드리면 아래와 같습니다.
Input.GetAxis("Mouse X") 는 Update() 가 호출될 때마다 그동안의 마우스 좌우 이동량을 나타냅니다.

xmove += Input.GetAxis("Mouse X"); // 마우스의 좌우 이동량을 xmove 에 누적합니다.

그러니까 마우스를 오른쪽으로 3의 거리만큼 이동했는데 처음 2만큼 이동했을 때 Update() 메소드가 호출되고,
다시 1만큼 이동하고 나서 Update() 메소드가 호출된다면 총 이동거리는 3이지만, 각각 나누어 2와 1이 호출됩니다.
그렇다면 3이란 이동량을 계산하기 위해서는 2와 1을 더해주어야겠지요?

이 스크립트는 마우스의 좌우 이동량에 대한 총 합계를 항상 계산하는 부분입니다.
참고로 '+=' 기호는 '더해주어라' 라는 연산 기호입니다.

마우스 위아래 움직임도 마찬가지입니다. 상하 총 이동량을 계산하기 위해 아래 방법이 사용되었는데요.

ymove -= Input.GetAxis("Mouse Y"); // 마우스의 상하 이동량을 ymove 에 누적합니다.

xmove 는 더하기 ( += ) 방식이었던 반면 ymove 빼기 ( -= ) 방식입니다.

이는 마우스의 상하 움직임은 그 값이 반대이기 때문입니다.
마우스를 위로 움직이면 음수의 이동량 수치가 Input.GetAxis("Mouse Y"); 값으로 입력되고,
반면 마우스를 아래로 움직이면 양수의 이동량 수치가 Input.GetAxis("Mouse Y"); 값으로 입력되기 때문입니다.

이렇게 이동량을 계산해준 다음, 카메라가 회전할 쿼터니온이라는 회전값을 적용해 줍니다

transform.rotation = Quaternion.Euler(ymove, xmove, 0);

쿼터니온은 매우 복잡한 수학적 정의인데요, 사실 크레이도 이 부분은 알지 못합니다.
다만 사용법만 알 뿐이지요.

Quaternion.Euler(X, Y, Z) 는 X, Y, Z 축 회전을 적용한 오일러 각도를 쿼터니온 각도로 변환해 줍니다.
오일러 각은 그냥 눈에 보이는 수치대로 X축을 얼만큼 회전했고 Y축을 얼만큼 회전했는지에 대한 값입니다.

이 동작을 마치면 카메라의 방향만 회전하지 카메라가 플레이어를 비추지는 않습니다.
그러니 플레이어가 카메라의 시선에서 벗어날 수 있는데요.

카메라의 위치를 조정해야 합니다.
해당 부분이 아래 스크립트입니다.

Vector3 reverseDistance = new Vector3(0.0f, 0.0f, distance); // 카메라가 바라보는 앞방향은 Z 축입니다. 이동량에 따른 Z 축방향의 벡터를 구합니다.
transform.position = player.transform.position - transform.rotation * reverseDistance; // 플레이어의 위치에서 카메라가 바라보는 방향에 벡터값을 적용한 상대 좌표를 차감합니다.

이 스크립트는 아래와 같이 회전된 카메라의 시야에 플레이어가 딱 정중앙에 위치하도록
카메라를 움직여줍니다.

카메라의 위치는 아래와 같은 공식으로 계산되는데요.
이 공식은 카메라가 바라보는 방향에서 지정거리에 플레이어가 위치하도록 카메라 위치를 상대적으로 조정합니다.

카메라 위치 = 플레이어의 위치 - 카메라 회전각 * (0,0,거리)

복잡한 수학공식은 넘어가고 그냥 이런 공식이 있다는 것만 알아 둡시다.

필요하신 분에게 도움이 되셨을지 모르겠군요.
오늘도 여기까지 읽어주셔서 감사합니다.


다음 챕터. 3인칭 플레이어 조작

itadventure.tistory.com/399

 

유니티3D 플레이어 조작 #5. 3인칭 플레이어 조작

지난 챕터에서는 3인칭 시점으로 플레이어를 바라보는 카메라에 대해 알아보았는데요. itadventure.tistory.com/398 유니티3D 플레이어 조작 #4. 3인칭 플레이어 뷰! 지난 시간에서는 카메라가 플레이어

itadventure.tistory.com

 

반응형