게임을 개발할 때 3인칭 시점에서 플레이어를 따라가는 카메라를 구현하는 것은 매우 일반적입니다. 하지만 이 방식으로 구현 시, 카메라가 벽이나 장애물에 막혀 플레이어가 보이지 않게 되는 상황이 발생할 수 있습니다. 카메라의 위치를 조정하여 플레이어를 가리지 않도록 해야 합니다.
이번 포스칭에서는 Unity에서 벽에 의해 카메라가 가려질 때 이를 감지하고, 적절한 위치로 조정하는 방법을 공유합니다.
카메라가 장애물 앞에 위치한 걸 확인할 수 있습니다.
카메라는 플레이어를 따라가도록 설정되어 있으며, 특정 거리만큼 떨어져 위치하도록 합니다.플레이어의 위치에 거리 벡터를 더해 카메라가 플레이어와 일정 거리만큼 떨어진 채 유지하도록 했습니다.
CameraController.cs
: 카메라의 위치를 업데이트 하는 스크립트로, 카메라 오브젝트에 부착됩니다.Dist
: 플레이어와 카메라 사이의 거리 벡터입니다.// CameraController.cs의 일부
// 카메라의 위치 = 플레이어의 위치 + 일정 거리
transform.position = _player.transform.position + Dist;
플레이어의 위치를 원점으로 하여, 카메라가 위치한 방향으로 Ray
를 생성하여 쏩니다. 즉 플레이어와 카메라 사이에 장애물이 있는지 Raycast
를 이용하여 확인합니다.
// 플레이어의 위치에서 카메라 위치를 향하는 광선
Ray ray = new Ray(_player.transform.position, _dist);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, _dist.magnitude, LayerMask.GetMask("Wall")))
{
// 플레이어와 카메라 사이에 장애물이 있어, 시야가 차단된 경우
// 플레이어를 향한 카메라의 방향은 유지한 채, 거리만 가깝게 이동
Vector3 newDist = _dist.normalized * hit.distance * 0.8f;
// 카메라 위치 변경
transform.position = _player.transform.position + newDist;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static UnityEditor.Experimental.GraphView.GraphView;
public class CameraController : MonoBehaviour
{
[SerializeField]
GameObject _player;
[SerializeField]
Vector3 _dist = new Vector3(0, 5f, 6f);
void LateUpdate()
{
Ray ray = new Ray(_player.transform.position, _dist);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, _dist.magnitude, LayerMask.GetMask("Wall")))
{
Vector3 newDist = _dist.normalized * hit.distance * 0.8f;
transform.position = _player.transform.position + newDist;
}
else
{
transform.position = _player.transform.position + _dist;
}
}
}
Raycast를 활용하면 3인칭 카메라가 벽에 가려지는 문제를 해결할 수 있습니다. 카메라가 벽에 부딪히는 경우 이를 감지하여 적절한 위치로 조정하면 플레이어의 시야를 확보할 수 있습니다.
추후에는 좀 더 부드러운 카메라 이동을 위해 Lerp나 SmoothDamp을 활용하는 방식도 고려해볼 수 있습니다.