본문 바로가기
유니티3D

유니티3D 플레이어 조작 #6. 1/3인칭 시점 전환

지난 시간에는 3인칭 시점 상태에서 플레이어 조작에 대해 알아보았습니다.

itadventure.tistory.com/399

 

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

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

itadventure.tistory.com

기획팀에서 점점 욕심이 나기 시작했나 봅니다 :)
이번엔 이런 요구를 해왔다고 가정해 보도록 하지요.

3.
과거에 선보였던 1인칭 시점 조작모드를 함께 사용할 수 있게 해주세요.
초기에는 3인칭 시점 모드로 시작하되 마우스 중앙버튼 클릭으로 1인칭 시점 모드와
3인칭 시점 모드를 토글하여 번갈아 볼 수 있게 해 주시고,

4.
3인칭 시점 모드에서는 카메라가 플레이어를 따라오는데 100% 움직임이는 대로 정확하게 따라오는 것보다는
약간의 지연을 발생하여 부드러운 움직임이 되게 해주세요. ( 0.1초 가량, 시간조절 가능 )

얄미워도 다시 한번!
이렇게 요구를 해온다는 것은 "당신의 능력을 믿습니다!"라는 의미이기도 하지 않습니까?
뿌듯해 해야겠지요? ㅎㅎ
하지만, 전적으로 크레이는 모든 능력을 "나의 주인이신 하나님께서 주시는 것"으로 믿습니다 :)


1인칭 시점과 3인칭 시점의 가장 큰 차이는 다음과 같습니다.

카메라의 위치가 어디인가? 플레이어의 눈 앞인가? 등 뒤 쪽인가?

1인칭 시점은 카메라가 플레이어의 눈 앞에 위치해 있어야 합니다.

그리고 3인칭 시점이라면 카메라가 플레이어의 등뒤 어딘가에 위치해 있어야 겠지요.

그러니까 카메라의 위치만 잘 잡아주면 3번 이슈가 해결되는 것이지요.

마우스 버튼에 대해서는 지난 시간에 다룬 것과 비슷한 문제인데요.

이 경우는 마우스 버튼을 누르고 있는 동안 체크하는 것이 아니라,
한번 클릭할 때마다 한 차례씩 1인칭 / 3인칭 뷰가 서로 번갈아 동작하도록 해야 합니다.
그 때는 Input.GetMouseButton () 메소드가 아닌, Input.GetMouseButtonDown(버튼번호) 메소드를 사용해야 합니다.

이 메소드는 버튼을 한번 누르면 한번만 그 값을 true로 인식하며
더 이상 누르고 있어도 그 이후에는 계속 false 로 인식하기 때문입니다.

이제 구현 부분을 코드로 살펴보도록 할까요?

1인칭일 때 3인칭으로, 3인칭일때는 1인칭으로 전환하기 위해서는
현재 1인칭 상태인지 3인칭 상태인지 먼저 알아야 합니다.
그 것을 위해서 카메라 컨트롤러 클래스에 아래와 같은 변수를 선언합니다.
이 값으로 현재 1인칭인지, 3인칭인지 판단할 겁니다. 처음에는 3인칭으로 시작하도록 해봅시다.

private int toggleView=3; // 1=1인칭, 3=3인칭

그리고 마우스 가운데 버튼을 한번 클릭했을 때 작동하는 코드는 아래와 같습니다.
이 코드는 Update() 안에 있어도 버튼 클릭이 한번이면 한번만 실행됩니다.
간단히 toggleView 값을 한번은 1이 되었다가, 다시 한번 클릭하면 3이 되도록 하고 있습니다.

if (Input.GetMouseButtonDown(2))
    toggleView = 4 - toggleView;

이제 1인칭 3인칭 시점에 따라 카메라 위치가 왔다갔다 하도록 하면 되지요.

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

반영된 전체 코드는 아래와 같습니다.
이 코드를 CamController.cs 에 넣고 플레이를 진행해 주세요.

그러면 처음에는 3인칭 시점으로 시작했다가

마우스 중앙 버튼을 클릭하면 1인칭 시점으로 바뀌는 것을 확인할 수 있습니다.
이 상태에서 화살표키로 움직이고 마우스 우클릭으로 화면을 돌려보어도 3인칭 시점처럼 조작이 가능합니다.

이제 4번 문제를 맞닥뜨려 봅시다.
해외 소스를 찾아보니 아주 적절한 기능이 있는데요.
SmoothDamp 라는 벡터 함수를 통해 카메라를 서서히 따라가는 팔로워 기능을 만들수 있었습니다.

사용법은 아래와 같습니다.
SmoothTime 은 지연시간인데 크게 줄수록 카메라가 더 늦게 반응합니다.
그리고 velocity 는 현재 속도를 의미합니다.

public float SmoothTime = 0.2f;
private Vector3 velocity = Vector3.zero;
     :
transform.position = Vector3.SmoothDamp(
    transform.position,
    player.transform.position - transform.rotation * reverseDistance,
    ref velocity,
    SmoothTime);

위 내용이 들어간 최종장(?) 소스입니다

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;

    public float SmoothTime = 0.2f;
    private Vector3 velocity = Vector3.zero;

    private int toggleView=3; // 1=1인칭, 3=3인칭

    // Update is called once per frame
    void Update()
    {
        //  마우스 우클릭 중에만 카메라 무빙 적용
        if (Input.GetMouseButton(1))
        {
            xmove += Input.GetAxis("Mouse X"); // 마우스의 좌우 이동량을 xmove 에 누적합니다.
            ymove -= Input.GetAxis("Mouse Y"); // 마우스의 상하 이동량을 ymove 에 누적합니다.
        }
        transform.rotation = Quaternion.Euler(ymove, xmove, 0); // 이동량에 따라 카메라의 바라보는 방향을 조정합니다.

        if (Input.GetMouseButtonDown(2))
            toggleView = 4 - toggleView;

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

이 코드를 넣고 플레이시켜본 결과는 아래와 같습니다.
3인칭 모드에서 카메라가 약간 늦게 따라오는 감이 느껴지시나요? 처음 등장할때 특히나요 :)

필요하신 분께 도움이 되셨을지요 :)
오늘도 여기까지 읽어주셔서 감사합니다.


다음 챕터. 유니티3D 플레이어 이름 표시

itadventure.tistory.com/401

 

유니티3D 플레이어 이름표시

지난 챕터에서는 마우스 가운데 버튼 클릭으로 1인칭과 3인칭 모드를 번갈아 표시하는 부분을 다루어 보았었지요. 동시에 약간의 시간 지연을 두어 카메라의 부드러운 움직임도 다루어 보았습

itadventure.tistory.com