TPS 게임을 만들어보는 글이기 때문에 카메라 또한 TPS 게임에 맞게 세팅하는 글입니다.
1. Spring Arm
언리얼 엔진에서는 카메라를 세팅할 때 Spring Arm을 사용합니다.
공식 문서를 사랑하자!
공식 문서에 적혀있듯이 Spring Arm을 사용하면 아래와 같은 이점이 있습니다.
- 게임플레이 상황에 따라 카메라와 타켓 간의 거리를 조절할 수 있음
- 3인칭 시점을 만들 때
다른 오브젝트랑 카메라가 부딪혔을 때 카메라가 오브젝트랑 겹치지 않게 자동으로 위치를 이동해 줌
1-1. 코드
전방 선언을 통해 USpringArmComponent 포인터를 가진 _springArm 변수를 만든다.
class를 통한 전방 선언을 해주는 이유
전방 선언을 해주지 않으면 .h 파일에 #include “GameFramework/SpringArmComponent.h”을 작성해 주어야 합니다.
이럴 경우 .h 파일을 다른 파일에서 참조하게 될 때 #include “GameFramework/SpringArmComponent.h” 또한 참조하게 되면서 컴파일 시간과 의존성이 늘어나게 됩니다.이를 피하기 위해
.h파일에는 class USpringArmComponent* 를 통해 USpringArmComponent class 타입을 사용할 것임을 선언만 해주고
.cpp 파일에서 실제 이 USpringArmComponent의 h파일을 include 하면서 컴파일 시간과 의존성을 낮출 수 있습니다.(포인터인 이유도 USpringArmComponent 타입의 크기를 알 수 없기 때문에 포인터를 이용해 4바이트 크기로 처리할 수 있기 때문에 포인터를 사용하는 것입니다)
1
2
3
4
// APlayerCharacter.h
private:
UPROPERTY(EditAnyWhere, meta=(AllowPrivateAccess = "true"))
class USpringArmComponent* _springArm;
1
2
3
4
5
6
7
8
9
10
// APlayerCharacter.cpp
#include "GameFramework/SpringArmComponent.h"
APlayerCharacter::APlayerCharacter()
{
// _springArm에 USpringARmComponent 오브젝트 생성
_springArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraSpringArm"));
// 루트에 붙여준다.
_springArm->SetupAttachment(GetRootComponent());
}
2. Camera
2-1. 코드
카메라는 UCameraComponent 타입이며 #inlcude “Camera/CameraComponent.h”의 Header를 가지고 있다.
1
2
3
4
// APlayerCharacter.h
private:
UPROPERTY(EditAnyWhere,meta=(AllowPrivateAccess = "true"))
class UCameraComponent* _camera;
1
2
3
4
5
6
7
8
// APlayerCharacter.cpp
#include "Camera/CameraComponent.h"
APlayerCharacter::APlayerCharacter()
{
_camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
_camera->SetupAttachment(_springArm);
}
3. BP에서 확인
Characater BP의 컴포넌트에 Spring Arm / Camera가 잘 세팅되어 있는 것을 볼 수 있다.
이제 Spring Arm의 Transform과 Target Arm Length를 자신의 게임 상황에 맞게 BP에서 세팅해 보자.
필자 같은 경우는 아래와 같이 세팅했다.
- Position(0,0,110)
- Target Arm Length: 400
이제 세팅 및 테스트를 통해 결정된 값을 코드로 옮길 예정이다.
코드로 옮겨두어야 ACharacter(C++ 클래스)를 통해 객체를 생성할 때 카메라 세팅이 코드대로 초기화된다.
옮기지 않으면 매번 새롭게 세팅해주어야 한다
1
2
3
4
5
6
7
8
9
10
APlayerCharacter::APlayerCharacter()
{
_springArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraSpringArm"));
_springArm->SetupAttachment(GetRootComponent());
_springArm->TargetArmLength = 400.f; // Target Arm Length: 400
_springArm->SetRelativeLocation(FVector(0,0,110)); // Z가 100으로 위치 수정
_camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
_camera->SetupAttachment(_springArm);
}