[ 카메라 추적 ]
구현 코드
카메라가 캐릭터의 움직임을 따라가고 함께 이동하기 때문에, TopDownMovement 클래스에서 캐릭터 이동 메서드에 카메라 이동 코드를 구현하면 되지 않을까 하고 생각했다.
하지만 메서드를 구분해 놓는 것이 찾기도 쉽고 구현도 편할 것 같아서 CameraController 클래스를 새롭게 생성했다.
//최종 코드
public class CameraController : MonoBehaviour
{
private Camera camera;
public Transform chracterPos;
public Vector3 offset = new Vector3(0, 0, -10);
private void Awake()
{
camera = Camera.main;
}
private void LateUpdate()
{
Vector3 newPosition = chracterPos.position + offset;
camera.transform.position = newPosition;
}
}
트러블 슈팅
//문제점 1
private void Awake()
{
camera = Camera.main;
camera = GetComponent<Camera>();
}
//해결
private void Awake()
{
camera = Camera.main;
}
카메라를 움직이기 위해선서는 우선 카메라의 위치를 가져와야 한다. 처음에는 main 카메라를 가져오고, 해당 카메라의 컴포넌트를 가져오는 코드를 작성했다.
Camera.main은 태그가 MainCamera인 가장 먼저 활성화된 카메라를 찾는다. GetComponent<Camera>()는 해당 스크립트가 있는 오브젝트의 카메라를 찾는다. 하지만 CameraController는 Main Camera에 있으므로 둘은 동일한 카메라 컴포넌트를 반환하게 된다. 따라서 Camera.main 코드만 사용해서 코드 중복을 방지할 수 있다.
public Transform chracterPos;
private void LateUpdate()
{
Vector2 cameraPositon = camera.transform.position; //문제점 2
cameraPosition = chracterPos.position; //문제점 3
}
//해결
public Transform chracterPos;
public Vector3 offset = new Vector3(0, 0, -10);
private void LateUpdate()
{
Vector3 newPosition = chracterPos.position + offset;
camera.transform.position = newPosition;
}
Camera.main을 통해 카메라 컴포넌트에 접근해서 메인 카메라의 위치를 가져왔다.
하지만 카메라 위치는 오브젝트와 떨어져서 게임 세계를 비추기 때문에 3차원 공간이다. Transform 컴포넌트의 기본 세팅에서 z축이 -10인 것을 확인할 수 있다. 따라서 Vector2 타입이던 cameraPosition을 Vector3 타입으로 수정한다.
그리고 cameraPosition에 캐릭터 오브젝트의 위치를 할당한다. 그러나 단순히 위치 값을 할당한 것에 그쳐서 실제로 카메라의 위치가 변하지는 않는다. 이를 실제 카메라 위치에 반영해야 화면이 이동하게 된다.
카메라와 캐릭터의 위치 간 차이를 나타내는 offset 필드를 생성하고, 카메라 위치의 초기값 (0, 0, -10)을 할당한다. 그리고 카메라가 이동해야할 위치인 newPosition 필드에 캐릭터 위치와 offset 필드를 더한 값을 할당한다. 그 값을 실제 카메라 위치에 할당하면 화면이 캐릭터의 움직임에 따라 이동하게 된다.
LateUpdate 메서드에 구현한 이유
카메라 화면이 이동하는 코드를 LateUpdate 메서드에 구현한 이유는 카메라가 비추는 화면은 모든 오브젝트의 행동이 끝난 뒤여야 하기 때문이다. Update 메서드에서 오브젝트에 대한 변화를 처리하고, 이후 LateUpdate 메서드에서 모든 변경 사항이 반영된 상태를 찍는다.
[ 보간 적용 ]
Rigidbody 2D 컴포넌트가 있는 캐릭터 오브젝트에서 Interpolate를 None에서 Interpolate로 변경하면 수동 보간을 하지 않고도 카메라 화면의 움직임을 더욱 부드럽고 자연스럽게 할 수 있다. 현재 프로젝트에서는 캐릭터가 빠르지 않아서 큰 차이가 없지만, 오브젝트가 매우 빠른 속도로 움직여서 프레임 수가 많을 때에는 해당 설정을 해주면 카메라가 더욱 부드럽게 움직일 수 있다.
None은 보간을 적용하지 않는 것이고, Extrapolate는 현재 움직임을 기반으로 다음 움직임을 예측하는 것이다. 따라서 일부 상황에서는 자연스러운 움직임을 표현하지 못할 수 있다.
[ 회고 ]
지금까지 camera를 사용한 거라곤 ScreenToWorldPoint 뿐이라서 어떻게 시작을 해야 할지 고민이 됐다. 처음에는 단순히 캐릭터 움직임에 카메라 움직임을 한 번에 더해서 실행시키면 되겠다고 생각을 했다. 하지만 생각보다 카메라 화면을 움직이기 위해서는 더 많은 코드가 필요했다. 무엇보다 한 메서드에 캐릭터와 카메라의 이동이 같이 있으면 어떤 코드가 어떤 오브젝트인지 알아보기가 힘들었다. 그래서 카메라 화면 이동을 위한 클래스를 따로 생성했다. 코드를 다 구현하고 나니 생각보다 간단해서 놀랐다. 무엇보다 캐릭터를 따라서 화면이 이동하니까 정말 게임을 하는 느낌이 나서 재밌었다.
'Coding > Unity' 카테고리의 다른 글
[내일배움캠프 23일차 TIL] 스크립터블 오브젝트, 레이어 마스크, 비트 시프트 연산, 오브젝트 풀링, FindGameobjectWithTag (0) | 2024.05.17 |
---|---|
[내일배움캠프 21일차 TIL] 애니메이션 적용, 이름 입력, 씬 전환 시 데이터 유지, DontDestroyOnLoad (0) | 2024.05.14 |
[내일배움캠프 19일차 TIL] New Input System, 이벤트 처리 (0) | 2024.05.10 |
[내일배움캠프 18일차 TIL] 쿼터니언, 아크탄젠트 (0) | 2024.05.09 |
[내일배움캠프 17일차 TIL] 게임 엔진, PPU, 계층 구조, Input.GetAxis, 직렬화 (0) | 2024.05.08 |