상속은 한 클래스가 다른 클래스로부터 특징과 동작을 파생하는 과정을 말한다. C++ 클래스를 확장하면 새로운 파생 클래스를 만들 수 있다. 이렇게 생성된 클래스는 상속한 클래스(기반 클래스)의 속성을 유지할 수 있으며 해당 속성을 수정하거나 새로운 특징을 추가할 수도 있다. 캐릭터 클래스가 대표적인 예다.
캐릭터 클래스는 폰의 특별한 유형으로 언리얼 폰 클래스의 자손이다. 폰 클래스를 확장한 캐릭터 클래스는 여러 입력을 통해 캐릭터 움직임을 추가하는 이동 기능을 기본적으로 가진다. 기본적으로 캐릭터 클래스는 캐릭터가 생성된 월드에서 걷고, 뛰고, 점프하고, 날아다니고, 수영할 수 있는 기능을 사용자에게 제공한다.
캐릭터 클래스는 폰 클래스를 확장했으므로 폰의 모든 코드와 로직을 포함한다. 캐릭터 클래스를 확장하면 기존 컴포넌트들은 상속된 컴포넌트로 확장한 클래스에 전달된다.(캡슐 컴포넌트, 애로우 컴포넌트, 메시 컴포넌트)
상속된 컴포넌트는 제거할 수 없다. 설정은 변경할 수 있지만 기반 클래스에 추가된 컴포넌트는 항상 확장된 클래스에 존재한다. 여기서 폰 클래스가 기반 클래스고, 캐릭터 클래스는 확장된 클래스이다.
캐릭터 클래스는 다음과 같은 상속된 컴포넌트를 제공한다.
일반적으로 개발자는 c++에서 게임 및 캐릭터 로직 코드를 작성하고, 이렇게 작성된 클래스를 블루프린트에서 확장해 클래스에 에셋을 연결하는 등의 단순 작업을 처리하는 것을 선호한다. 예를 들어 개발자가 캐릭터 클래스를 상속하는 c++ 클래스를 생성하고 이동 및 점프 로직을 모두 이 클래스 안에서 작성한 후 이 클래스를 블루프린트에서 확장하면 필요한 애셋(스켈레탈 메시 및 애니메이션 블루프린트 등)으로 컴포넌트 설정을 업데이트 하고 필요한 경우 블루프린트에서 코드를 추가할 수 있다
C++ 나 블루프린트를 통해 캐릭터 클래스를 상속하면 이 클래스를 확장할 수 있다. 확장된 캐릭터 클래스는 캐릭터 클래스의 자식이 된다. 클래스 확장은 객체지향 프로그래밍의 강력한 부분이며 이를 통해 클래스는 다양한 깊이와 계층으로 확장될 수 있다.
c++ 클래스로 만든 MyThirdPeronChar.h를 열고 아래와 같이 카메라를 위한 변수를 선언해준다
// 플레이어 카메라의 자리 표시자 역할을 하는 스프링 암 컴포넌트
// 레벨에 배치된 지오메트리에 가려졌을 때 카메라가 대처하는 방법을
// 자동으로 제어해주기 대문에 이 컴포넌트를 쓰는 것을 권장함
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="MyTPS_Cam", meta=(AllowPrivateAccess="true"))
class USpringArmComponent* CameraBoom;
//캐릭터를 따라다닐 카메라
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="MyTPS_Cam", meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FollowCamera;
앞의 코드에서 2개의 컴포넌트를 정의했는데, 카메라 컴포넌트와 플레이어로부터 특정 거리에 카메라를 위치시키는 카메라붐 컴포넌트이다.
.h파일에 다음과 같은 헤더파일을 추가해준다
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
그리고 .cpp 파일에는 다음과 같은 헤더를 추가해준다
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
이 헤더파일들은 앞서 추가한 컴포넌트들에 해당하는 클래스를 추가하는 구문이다. 이를 통해 각 컴포넌트의 메서드와 정의에 접근할 수 있다.
//캡슐 콜리전 크기 정하기
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
// 컨트롤러가 회전할 때 캐릭터는 회전하지 않도록 설정한다
// 캐릭터가 카메라에 영향을 주도록 놔둔다
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
//캐릭터 무브먼트 생성
GetCharacterMovement()->bOrientRotationToMovement = true;
//카메라 붐을 생성한다(충돌 발생 시 플레이어 쪽으로 다가가게 만든다)
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 300.f;
CameraBoom->bUsePawnControlRotation = true;
//캐릭터를 따라다닐 카메라 생성
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
FollowCamera->bUsePawnControlRotation = false;
앞 코드의 마지막줄은 카메라를 폰의 회전과 바인딩 되도록 설정한다. 즉 폰이 회전하면 카메라도 폰의 회전과 함께 회전해야 한다.