
이번에는 언리얼 C++ 프로그래밍 튜토리얼의 "게임 조종 카메라" 편을 따라서 진행해 볼 것이다
게임 조종 카메라 | 언리얼 엔진 5.3 문서 (unrealengine.com)
이것을 통해 언리얼 엔진에서 카메라를 활성화시키고 전환하는 방법을 공부하게 될 것이다
우선 언리얼 엔진을 실행하고 새 프로젝트를 생성한다
[카테고리는 게임으로 하고 C++ 프로젝트로 한 뒤, 게임 시작용 콘텐츠를 포함시킨 상태로 프로젝트를 생성해 준다]
튜토리얼을 더 쉽게 이해하기 위해 [Content > StarterContent > Maps]에서 Minimal_Default 맵으로 변경해 준다
이제 월드에 카메라를 배치할 차례이다
카메라를 다루는 방법은 여러 가지가 있지만 이 튜토리얼에서는 그중에 2가지 방법을 다루고 있다
그중 첫 번째로는 먼저, 메인툴바에서 Create 탭을 선택하고 All Classes에서 Camera Actor를 찾아서 월드에 배치해 준다
[액터 패널에서 끌어다 사용해도 무관하다]
월드에 배치한 카메라를 선택하고 있으면 지금처럼 레벨 에디터의 뷰포트 우측 하단에 현재 카메라가 보고 있는 장면을 미리 보기로 볼 수 있다. 이 카메라가 월드에 배치되어 있는 액터들을 바라보게 배치한다
[액터를 생성할 때 생성되는 위치가 달라질 수 있으므로 못 찾을 시 아웃라이너에서 CameraActor를 선택 후 'F'키를 눌러 집중적으로 액터의 위치를 찾을 수 있다]
이때 카메라의 위치와 회전을 일일이 수정해서 원하는 위치를 바라보게 만들 수도 있지만 좀 더 간단한 방법으로는 파일럿 기능이 있다
아웃라이너 패널에서 카메라 액터에 우클릭하고 [Pilot 'CameraActor'] 항목을 선택한다 (단축키: Ctrl + Shift + 'P')
그러면 카메라가 바라보고 있는 장면으로 뷰포트의 시야가 바뀌는데 이 상태에서 뷰포트를 조정해서 카메라가 바라보게 할 장면을 잡아 낼 수 있다
다시 월드 아웃라이너 패널에서 카메라 액터에 우클릭하고 [Stop Piloting 'CameraActor']을 선택하면 파일럿 모드를 종료하고,\
카메라는 뷰포트가 바라보는 상태로 세팅된다
카메라를 다루는 방법 두 번째로는, 기본 카메라 액터가 아닌 컴포넌트를 이용하여 배치해 볼 것이다
액터 배치 패널에서 원하는 액터를 골라서 월드에 배치한다 (본인은 'Cylinder' 액터를 배치하였다)
액터를 배치하고 나면 Details 패널에서 액터의 인스턴스를 선택한 후, [Add] 버튼을 누른 다음 카메라 컴포넌트를 찾아서 추가해 준다
그리고 루트 컴포넌트와 카메라 컴포넌트를 이용하여 위치를 맞춰준다
[루트 컴포넌트에 실린더, 하위 컴포넌트에 카메라가 있기 때문에 실린더를 선택하고 우클릭해서 파일럿 모드를 사용할 수 있다]
위치 세팅이 끝나면 카메라 컴포넌트의 Constraint Aspect Ratio, 종횡비 제한 옵션을 켜준다
[종횡비 제한 설정은 중요한 작업은 아니지만 첫 번째 카메라(CameraActor)의 종횡비 제한 옵션이 켜져 있기 때문에 카메라 사이의 부드러운 전환을 위해서 켜주는 것이다]
카메라 배치가 끝났으니 카메라 뷰를 제어할 클래스를 만들어 보자
메뉴바에서 [Tools > New C++ Classes] 항목을 선택하여 C++ 클래스를 추가한다
(Actor 클래스를 부모 클래스로 지정하고 CameraDirector라는 이름으로 클래스를 생성해 보자)
클래스 생성이 끝나면 헤더 파일로 이동해서
AActor 포인터 타입의 CameraOne, CameraTwo, float 타입의 TimeToNextCameraChange 변수를 선언해주고 나서, UPROPERTY선언자를 붙이고 EditAnywhere지정자를 넣어 에디터에서도 편집을 할 수 있도록 한다
그다음 소스 파일에서 "Kismet/GameplayStatics.h" 헤더파일을 include 선언하라
그다음에는 Tick 함수로 가서 코드를 작성해 보자
먼저 const float으로 카메라의 포커스를 다음 카메라로 변경하는 시간을 정의하는 TimeBetweenCameraChanges 변수를 선언하고 기본 값을 2로 설정해 준다[여기서 변수를 const로 지정하는 것은 이 변수의 값은 상수로 다른 값으로 변경될 수 없음을 의미한다]
그리고 const float으로 카메라가 블랜딩 되며 부드럽게 전환될 시간을 정의할 SmoothBlendTime을 선언하고 0.75로 지정해 준다
다음으로 TimeToNextCameraChange 변수에서 DeltaTime을 빼주고
TimeToNextCameraChange 값이 0보다 작아지면 다시 TimeBetweenCameraChanges를 더해주도록 코드를 작성한다
이제 카메라를 전환하는 코드를 작성할 차례이다
UGamePlayStatics 클래스의 GetPlayerController 함수를 사용해서 로컬 플레이어의 컨트롤을 처리하는 액터를 찾는다
[첫 번째 매개변수에는 this 객체(일반적으로 액터), 두번째 매개변수에는 index 0(보통 첫번째 플레이어)]
따라서 controller 변수는 현재 월드에서 가져온 플레이어 컨트롤러에 대한 포인터를 가지게 된다
이 컨트롤러는 게임에서 플레이어의 입력 및 기타 플레이어 관련 동작을 제어하는 데 사용되고, 이 컨트롤러를 사용해서 플레이어와의 상호작용 및 게임 로직을 구현할 수 있다
이 Player Controller를 가져온 다음 지금 바라보는 타깃이 CameraOne이 아니라면 APlayerController 클래스의 SetViewTarget 함수로 CameraOne을 카메라로 변경한다
만약 지금 바라보는 타깃이 CameraTwo가 아니라면 SetViewTargetWithBlend 함수로 CameraTwo를 카메라로 변경해 준다
[여기서 SetViewTarget 함수와 SetViewTargetWithBlend 함수의 차이점은 카메라를 전환할 때 바로 컷 해서 들어갈지, 부드럽게 카메라를 이동시키면서 들어갈지에 대한 것이다]
코드를 작성하면 모두 저장하고 에디터로 돌아가서 컴파일해 준다
컴파일이 끝나면 CameraDirector를 월드에 배치하고 디테일 패널에 배치된 CameraDirector 인스턴스를 선택해서 CameraOne과 CameraTwo에 카메라 컴포넌트가 부착된 Cylinder(원기둥 모양)와 CameraActor를 각각 할당해 준다
할당이 끝나고 게임을 플레이시켜 보면
먼저 CameraOne(Cylinder)에 할당된 카메라로 시야가 바뀔 때는 빠르게 컷으로 전환되고 CameraTwo(CameraActor)에 할당된 카메라로 시야가 바뀔 때는 카메라가 이동하면서 부드럽게 바뀌는 것을 볼 수 있다
이 카메라 기능을 잘 이용하면 플레이어가 카메라를 직접 제어하지 않는 게임에서 카메라 사이의 전환을 자연스럽게 연출할 수 있다
이 다음 글에서는 직접해보기라는 항목으로 진행해볼 것이다
VR게임 개발을 위한 언리얼엔진/C++ 공부한 내용 끄적이기...
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!