[Unity] Camera

이정석·2023년 6월 27일
0

Unity

목록 보기
6/22

Camera

게임에서 카메라의 구도나 시점에 따라 화면이 달라진다. 3인칭으로 캐릭터의 뒷모습을 따라가거나 1인칭으로 캐릭터의 시점으로 보는 등 여러가지 카메라 조작이 필요하다.

카메라를 조작하는 Component Script를 만들어서 카메라의 위치나 속성을 제어할 수 있다.

1. 캐릭터 시점고정

Camera Object를 캐릭터 Object의 하위 Object로 설정하면 Camera Object의 위치는 캐릭터의 위치에 영향을 받는다. Camera Position상위 Object Positon의 상대적인 위치이다.
Camera01

2. World좌표 시점고정

시점은 고정되었지만 캐릭터가 회전할때 카메라도 같이 회전해 매우 어지러운 상황이 발생한다. 캐릭터가 바라보는 방향에 관계없이 World좌표로 캐릭터와의 상대위치를 고정시켜버리면 해결이 된다.
Camera02

World좌표로 어떻게 카메라를 고정시키는가?

Camera의 위치를 조작하기 위해 하나의 Component Script를 작성한다. Script에는 다음과 같은 내용들이 필요하다.

1. 따라갈 Obejct
2. View Mode
3. World죄표계 내의 상대적인 위치
  • 따라갈 Obejct

카메라가 촬영할 Object로 Camera Obejct는 촬영할 Object에 대해서 알고 있어야 한다. 촬영할 Object를 받아오는 방법에는 직접 설정, 다른 코드에서 받아오기등 여러 방법이 있다.

  • View Mode, World죄표계 내의 상대적인 위치

카메라가 촬영할 기법(?)에 따라 카메라의 상대적인 위치가 달라진다. 예를 들면, 일반 RPG같은 경우 쿼터뷰를 사용할 수 있고 다른 게임에서는 탑뷰를 사용할 수 있다. 이 역시 직접 설정과 같은 방식으로 초기화 할 수 있다.

GameObject _player;
Vector3 _delta;
void Update(){
	transform.position = _player.transform.position + _delta;
}

transform.LoockAt(_player.transform)을 사용하면 촬영할 Obejct를 주시하도록 할 수 있다.


Update

위 코드대로 구현하면 실제 이동하는 화면은 캐릭터가 부들부들 떨면서 이동을 하게 되는데 캐릭터의 Update카메라의 Update의 실행순서가 정해지지 않았기 때문이다.

  • 카메라의 이동
  • 캐릭터의 이동

둘 중 무엇이 먼저 실행되는지는 모른다.

1. 이벤트 함수

Component Script를 처음 만들면 Start()Update()가 자동으로 작성되어 있는데 이 두 함수가 이벤트 함수이다. 이벤트 함수는 GameObject의 생명주기에 실행되는 함수라고 할 수 있는데 위 2개 말고 많은 이벤트 함수가 존재한다.

Initialization, Editor, Physics, Game logic에 많은 함수들이 있지만
Unity 공식 문서를 참고하자

2. LateUpdate

위 문제상황을 해결하기 위해 GameLogic의 Update문의 실행순서를 보자.(https://docs.unity3d.com/kr/2021.3/Manual/ExecutionOrder.html)
Unity 공식문서 GameLogic
함수 실행 순서를 보면 Update()가 가장 먼저 실행되고 애니메이션이 Update된 후 LateUpdate()를 실행한다. 우리는 캐릭터의 이동을 먼저한 뒤 카메라의 이동을 하고 싶기 때문에 Camera Component Script의 Update()LateUpdate()로 바꿔준다.

GameObject _player;
Vector3 _delta;
void LateUpdate(){
	transform.position = _player.transform.position + _delta;
}

3. Wall

만약 다음사진과 같이 카메라와 플레이어 사이에 벽과같은 장애물이 있다면 플레이어가 보이지 않을 것이다.

문제 상황은 카메라와 캐릭터 사이에 벽이 있는 상황이다. 이 상황은 두개의 단계가 필요하다.
  • 카메라와 캐릭터 사이에 벽을 탐지하는 방법

카메라와 캐릭서 사이의 장애물을 탐지하는 것이다. Raycast를 사용하면 장애물 탐지를 활용할 수 있다.

  1. 캐릭터의 위치
  2. 카메라의 상대위치
  3. 결과 반환용 RaycastHit
  4. Raycast 범위
  5. 장애물(벽)탐지를 위한 LayerMask

총 5개의 정보를 이용한 Raycast는 아래와 같이 구현할 수 있다.

 RaycastHit hit;
 if (Physics.Raycast(_player.transform.position, _delta,
 						out hit, _delta.magnitude, LayerMask.GetMask("Wall"))){
	//내용
}
  • 벽이 있을 때의 카메라 처리

위 코드의 주석에 해당하는 부분은 구현하고자 하는 내용을 작성하면된다. 카메라의 위치를 바꾸거나 캐릭터와 카메라 사이의 거리를 좁히는 방법이 있다.

다음 코드는 캐릭터와 카메라 사이의 거리를 좁히는 방법에 대한 코드이다.

float dist = (hit.point - _player.transform.position).magnitude * 0.8f;
transform.position = _player.transform.position + _delta.normalized * dist;
  1. dist: Raycast의 충돌지점과 캐릭터의 magnitude는 벽과 캐릭터 사이의 distance(내분점까지의 거리)를 의미하고 일정비율(0.8)만큼 당긴만큼이 새로운 Camera의 거리이다.
  2. 원래 Camera의 상대위치의 방향성분을 normalized를 이용해 구한뒤 dist만큼 떨어진 거리로 설정한다.

Camera04

profile
게임 개발자가 되고 싶은 한 소?년

0개의 댓글