언리얼엔진5 공부

언리얼엔진 C++ 챕터2 - 1. Character_클래스를_활용한_캐릭터_구현하기

Client Side 2025. 9. 19. 23:20
더보기

서바이벌 아케이드 게임 만들기 개요

 

게임내용

레벨 상에서 랜덤으로 스폰하는 코인, 힐링 아이템, 지뢰들.

지뢰들을 피하면서 최대한 많은 코인들을 획득해나가는 게임.

레벨은 3단계로 나눠짐.

점점 더 공간이 좁아지고, 점점 더 많은 지뢰.

체력이 0이되면 게임이 종료가 되고, 3단계를 모두 통과하면 점수판에 점수가 기록이 되면서 이전에 플레이한 플레이어들과 점수를 비교할 수 있음.

 

게임 구현 프로세스

1. 캐릭터 구현

2. 캐릭터 입력 매핑 구현

3. 캐릭터 기본 동작

4. 캐릭터 애니메이션 적용

5. 아이템 설계하기

6. 아이템 상호작용

7. 아이템 랜덤 스폰 및 레벨 별 각 아이템 개수 설정

8. 캐릭터 데미지 및 아이템 점수 관리 시스템

9. 웨이브 시스템을 통한 게임 흐름 제어

10. HUD에 실시간 정보 반영

11. 게임 흐름에 맞춘 메뉴 UI 구현

12. UI 애니메이션 효과 및 3D 위젯 UI 구현

13. 파티클 효과 적용 (지뢰 폭발, 아이템 습득)

14. 사운드 효과 적용 (지뢰 폭발 사운드, 아이템 습득, 발걸음)

15. 프로젝트 배포

 

1. GameMode 클래스의 역할 - 총괄 관리자

  • 플레이어 Pawn/Character 스폰
  • PlayerController 지정
  • 게임 규칙 관리
  • GameState(전역 게임 데이터 관리) / PlayerState(플레이어별 정보 관리) 사용

 

2. GameMode 클래스 생성

새로운 C++ 클래스에서 GameMode 클래스를 생성한 후 블루프린트 클래스로 생성해준다. BP_SpartaGameMode.

프로젝트 세팅에서 게임모드기본값을 방금 만든 게임모드 클래스로 설정해준다. -> 게임모드 전역 설정.

만약 레벨별로 게임모드를 적용하고 싶으면, 월드 세팅 창에서 게임모드를 바꿔주면 된다.

전역 설정과 레벨 별 설정을 동시에 했으면, 레벨 별 설정이 우선이다.

 

3. Pawn과 Character 클래스 이해하기

  • Pawn 클래스
    • 플레이어가 소유할 수 있는 가장 상위 클래스.
    • 이동로직이나 충돌처리, 중력, 네트워크 이동을 위한 기능들이 기본적으로 포함되어 있지 않다.
    • 모든 단계를 직접 구현해야 하므로 사람 캐릭터를 처음부터 Pawn으로 만들기는 부담이 크다.
    • 이러한 특성 때문에  비행기, 드론, 카메라처럼 기존 캐릭터의 이동 방식을 벗어난 특수한 로직을 완전히 구현할 때 유용.
  • Character 클래스
    • Pawn을 상속받아 만들어진 자식 클래스 중 하나로, 기본적으로 UCharacterMovementComponent를 포함하고 있다.
      • 이동, 회전, 점프, 중력, 지형 따라가기, 네트워크 동기화 등 보행형 캐릭터에게 필요한 기능이 이미 구현되어 있어, 사람이 달리고 점프하는 형태의 캐릭터를 쉽게 만들 수 있다.
      • 여기에 미리 정의된 대표적인 함수들(예: MoveForward, MoveRight, Jump)이 존재하므로, 몇 줄의 코드만 추가해도 금방 캐릭터 움직임을 테스트할 수 있다.
    • 캐릭터를 구성하는 전형적인 요소들이 표준화되어 있어, 일반적인 인간형 캐릭터를 만드는 데 최적화되어 있다. 
      • 단, 자동차나 비행기처럼 완전히 다른 이동 방식을 구현할 때는 Character 내부에 탑재된 기능들이 오히려 방해가 될 수 있다. 이런 경우에는 Pawn을 직접 확장해서 사용하는 것을 고려해야 한다.

 

4. Character 클래스 생성

C++로 캐릭터 클래스를 생성 후 블루프린트로 생성해준다.

 

1) CapsuleComponent (Root Component)

 

  • 캐릭터가 벽이나 지형에 출동하는 범위를 정의하는 콜리전 컴포넌트.

 

2) ArrowComponent

  • 캐릭터가 어느 방향을 바라보고 있는지를 표시하기 위해 씬에 화살표를 띄어주는 컴포넌트. 

3) SkeletalMeshComponent

  • 캐릭터의 3D 모델과 애니메이션을 적용하는 컴포넌트.
  • Skeletal Mesh, Anim Blueprint 등을 여기로 할당해 캐릭터의 외형과 동작을 제어한다.

4) CharacterMovementComponent

  • 캐릭터의 이동, 점프, 중력, 네트워크 동기화 등 물리적 이동로직을 담당하는 핵심 컴포넌트.
  • 언리얼에서 제공하는 주요 이동 함수 (MoveFoward, MoveRight, Jump)가 이미 연결되어 있어, 최소한의 코드만으로 캐릭터 조작을 구현할 수 있다.

5. 카메라 생성

3인칭 게임을 만들기 위해 캐릭터의 뒤에서 바라보는 카메라를 생성해야 한다.

카메라와 그 카메라를 컨트롤하는 스프링 암을 추가해야 한다.

스프링암은 카메라 삼각대와 같다. 

 

	USpringArmComponent* SpringArmComp;
	UCameraComponent* CameraComp;

 

멤버변수에 이렇게 넣어주고 헤더에 아래와 같이 전방선언(미리선언)을 해준다.

이 변수 하나를 위해 헤더를 추가하는건 메모리를 많이 잡아먹기때문에 모든 헤더를 다 추가해주지는 않는다.

헤더파일에 모든 것을 포함하면 그 헤더를 사용하는 모든 파일이 변경될 때마다 다시 컴파일해야 한다/

이렇게 우선 미리선언을 통해 컴파일이 문제없이 될 수 있도록 한다.

그리고 실제 헤더파일 추가는 cpp 파일에 해준다.

포인터나 참조로만 사용할 때 이렇게 사용할 수 있다.

class USpringArmComponent;
class UCameraComponent;

 

이제 그 다음  cpp 파일에 아래와 같이 헤더를 추가해준다.

#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"

 

 

 

Character.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "SpartaCharacter.generated.h"

class USpringArmComponent; // 스프링 암 관련 클래스 헤더
class UCameraComponent; // 카메라 관련 클래스 전방 선언

UCLASS()
class SPARTAPROJECT_API ASpartaCharacter : public ACharacter
{
		GENERATED_BODY()

public:
		ASpartaCharacter();

protected:
	  // 스프링 암 컴포넌트
	  UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
	  USpringArmComponent* SpringArmComp;
	  // 카메라 컴포넌트
	  UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
	  UCameraComponent* CameraComp;
	
		virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; // 이 함수는 이후에 다루게 되니, 우선 삭제하기 않고 둡니다.
};

 

 

 

 

Character.cpp

#include "SpartaCharacter.h"
// 카메라, 스프링 암 실제 구현이 필요한 경우라서 include
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"

ASpartaCharacter::ASpartaCharacter()
{
		// Tick 함수는 우선 꺼둡니다.
		PrimaryActorTick.bCanEverTick = false;
		
		// (1) 스프링 암 생성
    SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
    // 스프링 암을 루트 컴포넌트 (CapsuleComponent)에 부착
    SpringArmComp->SetupAttachment(RootComponent);
    // 캐릭터와 카메라 사이의 거리 기본값 300으로 설정
    SpringArmComp->TargetArmLength = 300.0f;  
    // 컨트롤러 회전에 따라 스프링 암도 회전하도록 설정
    SpringArmComp->bUsePawnControlRotation = true;  

    // (2) 카메라 컴포넌트 생성
    CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
    // 스프링 암의 소켓 위치에 카메라를 부착
    CameraComp->SetupAttachment(SpringArmComp, USpringArmComponent::SocketName);
    // 카메라는 스프링 암의 회전을 따르므로 PawnControlRotation은 꺼둠
    CameraComp->bUsePawnControlRotation = false;
}

void ASpartaCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
		Super::SetupPlayerInputComponent(PlayerInputComponent);
}