유니티

카메라(Camera)

코다람쥐 2022. 2. 4. 15:35

1. 카메라 컴포넌트

Culling Mask : 카메라에 투영할 레이어를 설정

Field of View : 카메라가 투영할 범위

Clipping Planes-Near : 카메라에서 가장 가까운 물체가 보이는 최소거리

Clipping Planes-Far : 카메라에서 가장 먼 물체가 보이는 최대거리

 

나머지는 유니티 문서 참조

 

2. 카메라 컨트롤러

카메라를 플레이어에 귀속시키기 위해서는 카메라를 플레이어의 자식객체로 만드는 방법이 있다.

하지만 그렇게하면 플레이어가 회전을 할 때 카메라도 너무 어지롭게 회전하기 때문에 CameraController스크립트를 통해 카메라의 움직임을 플레이어에 귀속시켜보자.

 

 

Define.cs

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

public class Define
{
    public enum CameraMode // 카메라의 뷰 모드를 열거형으로 표시
    {
        QuaterView,
    }
}

 

CameraController.cs

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

public class CameraController : MonoBehaviour
{
    [SerializeField]
    Define.CameraMode _mode = Define.CameraMode.QuaterView; // 뷰 모드 설정

    [SerializeField]
    Vector3 _delta = new Vector3(0.0f, 6.0f, -5.0f); // 카메라 위치

    [SerializeField]
    GameObject _player = null; // 플레이어
    
    void LateUpdate() // 카메라 떨림 현상을 제거하기 위해사용
    {
        if(_mode == Define.CameraMode.QuaterView)
        {
            transform.position = _player.transform.position + _delta; // 카메라 위치를 플레이어에 귀속
            transform.LookAt(_player.transform); // 카메라는 플레이어 위치를 바라봄
        }
    }
}

LateUpdate를 사용하는 이유는 Update에서 처리하면 카메라 이동과 플레이어 이동의 순서가 뒤죽박죽이 된다. 그래서 매 프레임마다 2분의 1확률로 먼저 실행되는 코드가 달라지기 때문에 카메라 떨림현상이 발생한다.

이러한 현상을 바로잡기 위해서 순서를 정해주면 되는데 플레이어 이동이 먼저 실행된 후 카메라 이동이 실행되게 하기 위해 LateUpdate에서 카메라 이동을 처리해주었다.

 

참고로 LateUpdate는 Update보다 나중에 실행된다.

 

 

3. 장애물을 피해 플레이어를 잡는 카메라

CameraController.cs

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

public class CameraController : MonoBehaviour
{
    [SerializeField]
    Define.CameraMode _mode = Define.CameraMode.QuaterView; // 뷰 모드 설정

    [SerializeField]
    Vector3 _delta = new Vector3(0.0f, 6.0f, -5.0f); // 카메라 위치

    [SerializeField]
    GameObject _player = null; // 플레이어
    
    void LateUpdate() // 카메라 떨림 현상을 제거하기 위해사용
    {
        if(_mode == Define.CameraMode.QuaterView)
        {
            RaycastHit hit;
            if (Physics.Raycast(_player.transform.position, _delta, out hit, _delta.magnitude, LayerMask.GetMask("Wall")))
            {
                // 충돌한 물체의 좌표 * 0.8만큼 카메라 위치 이동
                float dist = (hit.point - _player.transform.position).magnitude * 0.8f;
                transform.position = _player.transform.position + _delta.normalized * dist;
                
            }
            else
            {
                transform.position = _player.transform.position + _delta; // 카메라 위치를 플레이어에 귀속
                transform.LookAt(_player.transform); // 카메라는 플레이어 위치를 바라봄
            }
        }
    }

    public void SetQuaterView(Vector3 delta)
    {
        _mode = Define.CameraMode.QuaterView;
        _delta = delta;
    }
}

레이캐스팅을 이용하여 구현하였고 코드 분석은 주석으로 해놓았다.