본문 바로가기

공부/이득우의 언리얼 프로그래밍

[Study] Part 2 - 언리얼 엔진 게임 제작 기초 (1/15)

728x90
반응형

 

 

  • 정리
    1. 게임 콘텐츠 구조의 이해
    2. 게임 프레임웍의 구성 요소 살펴보기
    3. 단순한 게임 구조에서 출발해 점점 복잡한 게임으로 확장하는 제작 과정을 이해
    4. C++ 프로젝트 구성을 위한 기본 설정
    5. 게임 구성 요소를 폴더별로 분류하고, 헤더 참조를 최소화하는 규칙 수립

 

 

  • 게임 콘텐츠의 구조
    • 게임 제작을 위해 언리얼 엔진은 자체적으로 설계한 프레임웍을 제공
    • 게임플레이 프레임웍(Gameplay Framework)이라고 부름 (= 게임 프레임웍)
    • 언리얼 게임 프레임 웍의 각 구성 요소를 파악하고, 이를 확장하면서 게임을 제작하는 것을 권장

 

 

 

  • 월드(World)
    • 게임 콘텐츠를 담기 위해 제공되는 가상의 공간
    • 시간, 트랜스폼, 틱을 서비스로 제공
    • 월드 세팅이라는 콘텐츠 제작을 위한 기본 환경 설정을 제공
    • 기본 단위는 액터(Actor)로 정의, 액터 클래스는 언제나 접두사 A를 사용

 

 

  • 게임 모드(Game Mode)
    • 게임 규칙을 지정하고 게임을 판정하는 최고 관리자 액터. 형태가 없음
    • 언리얼 엔진에서 하나의 게임에는 반드시 하나의 게임 모드만 존재
    • 게임 모드에서 입장할 사용자의 규격을 지정할 수 있음
    • 멀티플레이어 게임에서 판정을 처리하는 절대적 권위의 심판

 

 

 

  • 기믹(Gimmick)
    • 게임 진행을 위한 이벤트를 발생시키는 사물 액터
    • 주로 이벤트 발생을 위한 충돌 영역을 설정, 트리거(Trigger)
    • 트리거를 통해 캐릭터와 상호 작용하고, 월드에 액터를 스폰해 콘텐츠를 전개

 

 

 

  • 플레이어(Player)
    • 게임에 입장한 사용자 액터. 형태가 없음
    • 게임 모드의 로그인을 통해 사용자가 게임 월드에 입장하면 플레이어가 생성
    • 싱글 플레이 게임/컨텐츠 = 0번 플레이어
    • 사용자와의 최종 커뮤니케이션 담당 (ex 입력 장치의 해석, 화면 장치로의 출력)

 

 

 

  • 폰(Pawn)
    • 무형의 액터인 플레이어가 빙의해 조종하는 액터
    • 길찾기 사용, 기믹 및 다른 폰과 상호작용

 

 

 

 

  • 새로운 C++ 클래스를 추가하면 다음과 같은 컴파일러 에러가 뜰 때가 있다.

컴파일러 에러
Reload All

  • 이는 경로가 안맞기 때문에 그렇다. Reload All을 눌러 다시 리로딩을 해주고 Build.cs에 한 줄을 추가해 준다.

 

 

 

using UnrealBuildTool;

public class ArenaBattle : ModuleRules
{
	public ArenaBattle(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

		PublicIncludePaths.AddRange(new string[] { "ArenaBattle" });  // 모듈 이름 적어서 추가해주기
	
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });

		PrivateDependencyModuleNames.AddRange(new string[] {  });

		// Uncomment if you are using Slate UI
		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
		
		// Uncomment if you are using online features
		// PrivateDependencyModuleNames.Add("OnlineSubsystem");

		// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
	}
}
  • ArenaBattle.Build.cs

 

  • GameMode를 새로 만든 ABGameMode로 변경해주고, GameModePlayerController ClassABPlayerController로 변경해준다.
#include "Game/ABGameMode.h"
#include "ABGameMode.h"
#include "Player/ABPlayerController.h"

AABGameMode::AABGameMode()
{
	// DefaultPawnClass
	PlayerControllerClass = AABPlayerController::StaticClass();		// C++ 클래스라 헤더파일을 추가하고 AABPlayerController의 클래스를 가져올 수 있다.
}
  • AABGameMode.cpp

 

변경된 Player Controller Class

 

 

  • 3인칭 캐릭터 플레이는 기존 템플릿을 재사용하기 위해서 C++ 클래스로 만들어지지 않은 기존 블루프린트 클래스의 주소를 Copy Reference를 통해 에셋주소를 가져온다.
    • Default Pawn으로 사용할 예정

Copy Reference

 

 

#include "Game/ABGameMode.h"
#include "ABGameMode.h"
#include "Player/ABPlayerController.h"

AABGameMode::AABGameMode()
{
	static ConstructorHelpers::FClassFinder<APawn> ThirdPersonClassRef(TEXT("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"));		// 클래스형에 대해서는 Copy Reference로 들고온 에셋주소의 ''는 생략해 주고 경로만 입력해주고, 클래스 정보를 가져올 것이기 때문에 _C를 붙여 준다.

	if (ThirdPersonClassRef.Class)  // 가지고 온 ThirdPersonClassRef.Class가 참인지
	{
		DefaultPawnClass = ThirdPersonClassRef.Class;
	}
	// DefaultPawnClass
	PlayerControllerClass = AABPlayerController::StaticClass();		// C++ 클래스라 헤더파일을 추가하고 AABPlayerController의 클래스를 가져올 수 있다.
}
  • ABGameMode.cpp
  • 클래스형에 대해서는 Copy Reference로 들고온 에셋주소의 ''는 생략해 주고 경로만 입력해주고, 클래스 정보를 가져올 것이기 때문에 _C를 붙여 준다.

 

 

 

정상적으로 변경된 모습

 

 

  • 시작하자마자 포커스를 뷰 포트 안으로 보내주는 코드 작성
void AABPlayerController::BeginPlay()
{
	Super::BeginPlay();		// override의 경우 Super 붙이기

	FInputModeGameOnly GameOnlyInputMode;		// 구조체 선언
	SetInputMode(GameOnlyInputMode);			// 구조체 넘기기 (시작하자마자 포커스가 뷰 포트 안으로 들어가게 된다.)
}
  • AABPlayerController.cpp

 

  • 에셋 직접 참조를 통해 헤더파일 의존성 줄이기
#include "Game/ABGameMode.h"
#include "ABGameMode.h"

AABGameMode::AABGameMode()
{
	static ConstructorHelpers::FClassFinder<APawn> ThirdPersonClassRef(TEXT("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"));		// 클래스형에 대해서는 Copy Reference로 들고온 에셋주소의 ''는 생략해 주고 경로만 입력해주고, 클래스 정보를 가져올 것이기 때문에 _C를 붙여 준다.

	if (ThirdPersonClassRef.Class)
	{
		DefaultPawnClass = ThirdPersonClassRef.Class;
	}
	// DefaultPawnClass

	static ConstructorHelpers::FClassFinder<APlayerController> PlayerControllerRef(TEXT("/Script/ArenaBattle.ABPlayerController"));		// 위와 동일하게 적용. 이 경우 기본으로 클래스 정보가 복제된 것이기 때문에 _C를 붙이지 않아도 된다.

	if (PlayerControllerRef.Class)
	{
		PlayerControllerClass = PlayerControllerRef.Class;		// 이 경우 에셋으로부터 직접 참조를 받기 때문에 헤더 파일의 의존성을 줄일 수 있다.
	}
}
  • AABGameMode.cpp

 

  • 위와 동일하게 적용. 이 경우 기본으로 클래스 정보가 복제된 것이기 때문에 _C를 붙이지 않아도 된다.
    • 이 경우 에셋으로부터 직접 참조를 받기 때문에 헤더 파일의 의존성을 줄일 수 있다.

 

 

 

 

 

해당 포스트는 인프런의 <이득우의 언리얼 프로그래밍 Part2 -언리얼 게임 프레임웍의 이해>
강의를 수강하고 정리한 내용입니다.
 

이득우의 언리얼 프로그래밍 Part2 - 언리얼 게임 프레임웍의 이해 | 이득우 - 인프런

청강문화산업대학교에서 언리얼 엔진, 게임 수학, UEFN 게임제작을 가르치고 있습니다. - 이득우의 언리얼 C++ 프로그래밍, 넥슨 코리아 공식 교육 교재 선정 2023 - 스마일게이트 언리얼 프로그래

www.inflearn.com

 

 

 

 

 

728x90