Dev./UE 언리얼 엔진

[TIL_250131] Character 클래스를 활용한 캐릭터 구현하기(3인칭 카메라 설정, GameMode 설정)

raindrovvv 2025. 1. 31. 19:27

🗺️마인드맵

📒학습 내용

Pawn과 Character 클래스 이해하기

1 Pawn 클래스란 무엇일까?

  • Pawn은 플레이어나 AI가 '소유(Possess)'할 수 있는 가장 기본적인 클래스. 
    • 언리얼 엔진에서 '무언가를 조종한다'는 개념의 출발점이다.
  • 걷기, 달리기, 점프 같은 보행에 필요한 시스템들(캡슐 콜리전, 중력 적용, 지형 따라가기 등)을 직접 구현해야 한다.
    • 그래서 사람 캐릭터를 처음부터 Pawn으로 만드는 건 꽤나 부담스럽다.
  • 이동 로직, 충돌 처리, 중력, 네트워크 이동과 같은 기능들이 포함되어 있지 않다.
    • 따라서 비행기, 드론, 카메라처럼 기존의 Character 클래스가 제공하는 이동 방식에서 벗어난 특수한 로직을 자유롭게 구현할 수 있다.

2 Character 클래스란?

  • Character는 Pawn을 상속받아 만들어진 자식 클래스다.
    • 기본적으로 UCharacterMovementComponent를 포함하고 있다.
  • 이동, 회전, 점프, 중력, 지형 따라가기, 네트워크 동기화 기능이 이미 구현되어 있다.
    • 몇 줄의 코드만으로 캐릭터 움직임을 테스트할 수 있다.
  • 일반적인 인간형 캐릭터를 만드는 데 최적화되어 있다.
    • 자동차비행기처럼 다른 이동 방식을 구현할 때는 Character 클래스의 기능이 방해가 될 수 있다.
🤖Tip
: 만약 독특한 이동 방식이나 조작 방식을 가진 오브젝트를 만들고 싶다면, Pawn 클래스를 적극적으로 활용해 보는 게 좋다.
>> 반대로 기본적인 보행 캐릭터를 만들고 싶다면, 이미 다양한 기능이 포함된
Character 클래스를 사용하는 것이 개발 시간을 절약하는 데 도움이 된다!

  • CapsuleComponent:
    • 콜리전 컴포넌트로, 캐릭터의 물리적 크기를 정의.
  • ArrowComponent:
    • 캐릭터의 방향을 표시하는 컴포넌트. 주로 시각적 디버깅용.
  • SkeletalMeshComponent:
    • 캐릭터의 3D 모델과 애니메이션을 적용.
  • CharacterMovementComponent:
    • 캐릭터의 이동, 점프, 중력, 네트워크 동기화 등의 물리적 이동 로직 담당.

3 카메라 설정

<.h>

더보기
// Fill out your copyright notice in the Description page of Project Settings.  
  
#pragma once  
  
#include "CoreMinimal.h"  
#include "GameFramework/Character.h"  
#include "SP_Character.generated.h"  
  
class USpringArmComponent; // 스프링 암 관련 클래스 헤더 미리 선언(전방 선언)  
class UCameraComponent; // 스프링 암 관련 클래스 헤더 미리 선언(전방 선언)  
  
UCLASS()  
class START_API ASP_Character : public ACharacter  
{
    GENERATED_BODY()

public:
    // Sets default values for this character's properties  
    ASP_Character();
  
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera) // 객체 자체 변경은 불가. 내부 속성은 변경 가능
    USpringArmComponent* SpringArm;  
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera)
    UCameraComponent* Camera;
  
public:  
    // Called to bind functionality to input  
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;  
  
};

*Forward Declaration(전방 선언)
- 헤더 파일에서 클래스를 직접 포함하지 않고 전방 선언을 사용하면, 실제로 해당 클래스의 정의가 필요한 cpp 파일에서만 포함하기 때문에 컴파일 시간이 단축된다.

<.cpp>

더보기
// Fill out your copyright notice in the Description page of Project Settings.  
#include "SP_Character.h"  
#include "GameFramework/SpringArmComponent.h"  
#include "Camera/CameraComponent.h"  
  
// Sets default values  
ASP_Character::ASP_Character()  
{  
    // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.  
    PrimaryActorTick.bCanEverTick = false;  
  
    SpringArm = CreateDefaultSubobject<USpringArmComponent>("Spring Arm");  
    SpringArm->SetupAttachment(RootComponent);  
    SpringArm->TargetArmLength = 300.0f; // 스프링 암의 길이를 설정  
    SpringArm->bUsePawnControlRotation = true; // 스프링 암이 Pawn의 컨트롤 회전을 따르게 한다.  
    Camera = CreateDefaultSubobject<UCameraComponent>("Camera");  
    Camera->SetupAttachment(SpringArm, USpringArmComponent::SocketName);  
    Camera->bUsePawnControlRotation = false; // 스프링 암이 따라가주기 때문에 카메라는 이 기능을 꺼줘야 한다.  
}  
  
// Called to bind functionality to input  
void ASP_Character::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)  
{  
    Super::SetupPlayerInputComponent(PlayerInputComponent);  
  
}

카메라 및 스프링 암 설정

  • SpringArm->bUsePawnControlRotation = true
    • 플레이어가 마우스를 움직이면(시야를 회전시키면) Controller의 회전 값이 변경되고, 이때 스프링 암도 같이 회전하도록 설정한다.
    • 결과적으로 카메라도 회전하여 3인칭 시점을 자연스럽게 구현할 수 있다.
  • Camera->bUsePawnControlRotation = false
    • 이미 스프링 암이 회전을 처리하므로, 카메라 자체는 PawnControlRotation을 사용하지 않도록 설정한다.
    • 만약 이 설정을 true로 한다면?
      • 고정된 카메라 시점이나 특정 시각적 연출을 필요로 하는 상황에서 사용될 수 있다. 예를 들어, 특정 이벤트나 컷씬에서 카메라 시점을 고정시켜야 할 때 사용될 수 있다.

✨C++ 클래스로 완성시킨 후에, 블루프린트로 상속시켜 사용하면 편하다!


4 게임모드 설정

 

<.h>

// Fill out your copyright notice in the Description page of Project Settings.  
#pragma once  
  
#include "CoreMinimal.h"  
#include "GameFramework/GameMode.h"  
#include "SP_GameMode.generated.h"  
  
UCLASS()  
class START_API ASP_GameMode : public AGameMode  
{  
    GENERATED_BODY()  
  
public:  
    ASP_GameMode();  
};

<.cpp>

// Fill out your copyright notice in the Description page of Project Settings.  
#include "SP_GameMode.h"  
#include "SP_Character.h"  
  
ASP_GameMode::ASP_GameMode()  
{  
    DefaultPawnClass = ASP_Character::StaticClass();  
}
  • DefaultPawnClass = ASP_Character::StaticClass();
    1. DefaultPawnClass는 UClass\ 타입 변수*로 클래스의 타입 정보가 필요하다.
    2. ASP_Character::StaticClass()를 사용하면 ASP_Character 클래스의 타입 정보를 얻을 수 있다.
      • StaticClass()는 리플렉션 시스템을 활용해 클래스의 메타데이터를 가져오는 역할을 한다.
      • 클래스 정보를 넘겨서 반환해야 할 때는 StaticClass를 많이 사용한다!
    3. 이를 통해 엔진이 게임 시작 시 사용할 기본 Pawn 클래스를 알 수 있게 된다.
타입 정보가 뭐지?
🤖 : 클래스는 일종의 설계도나 청사진이다. 타입 정보는 "이 설계도가 어떤 설계도인지"에 대한 설명서라고 생각할 수 있다. "이 클래스는 ASP_Character라는 타입이다"라는 정보를 제공한다고 보면 된다.
  • DefaultPawnClass 설정:
    • 게임 시작 시 DefaultPawnClass로 설정된 캐릭터는 Player Start 위치에 스폰된다.
      • Player Start는 기본 플레이어 캐릭터의 시작 위치를 지정하는 데 사용된다.
  • Player Start 없을 경우:
    • 맵에 Player Start가 없으면, 엔진은 캐릭터를 맵의 원점(0, 0, 0)에 스폰하려고 시도한다.
    • 이 경우 충돌 문제로 인해 스폰이 실패할 수 있다.
  • Player Start 추가 방법:
    • Place Actors 패널 > Basic 카테고리에서 Player Start를 선택하여 맵에 드래그 앤 드롭하여 추가한다.

 

🟣오늘의 옵시디언 현황