언리얼 엔진 공부하기 #8 [UE5]

신지한·2024년 4월 28일
0

개발노트

목록 보기
14/15
post-thumbnail

📢 개발노트에 앞서서

본 개발노트는 혼자서 언리얼 게임개발 독학하는 과정에서
공부한 내용들을 기록&공유하는 게시글이며
부족한점이 있을 수 있어 참고해서 봐주시면 감사하겠습니다

👉 이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해

❗ 본 게시글은 위 강의의 내용을 정리 및 실습한 게시글로 모든 내용은 대부분의 내용은 책이 출처입니다


📚 스터디 내용

0강에서는 언리얼 엔진을 효과적으로 공부하는 방법에 대한 강의였습니다. 아래는 필기를 한 강의 노트입니다

📖 0강 필기 노트

  • 언리얼엔진 5를 따라잡기엔 기술적 격차가 너무 커짐
  • 언리얼 엔진의 영향력이 커짐
  • 디지털 산업 전방위적으로 영향을 미침(방송, 영화, TV시리즈, 등...)
  • Native 접근 c++ : 안정성보다 성능 중시, 메모리를 직접 제어, Cache의 활용 극대화, 저수준 API의 직접 호출, 복사 작업의 최소화 저수준을 제어하면서 복잡한 로직을 관리할 수 있는 객체지향 언어
  • 하이레벨 OOP 언어 : 성능보다 안정성중시, 유지보수성 향상, 크래시로부터 보호, 자동 메모리 관리, 고질적 실수 예방
  • 언리얼 C++ 프로그래밍 : 성능과 안정성을 모두 지원, 모든 장점들을 흡수
  • 기초체력 : 언리얼 C++, 기본기 : 게임 프레임웍
  • 학습방법 안정성, 확장성이 높은 하이 레벨 설계
    1단계: 언리얼 오브젝트
    2단계: 모던객체지향설계
    3단계: 자료구조와 메모리
    4단계: 에셋과 빌드시스템
    성능과 메모리 관리를 위한 로우 레벨 제어
  • 기본기 학습방법
    1단계: 콘텐츠의 기본 구조
    2단계: 캐릭터 애니메이션
    3단계: 물리엔진과 이벤트
    4단계: 게임데이터와 인공지능
    5단계: 게임의 완성

1강에서는 언리얼 프로젝트 설치 및 간단한 C++ 실습을 진행했습니다. 아래는 필기를 한 강의 노트입니다

📖 1강 필기 노트

1. 기초설정

  • 언리얼엔진 설치
  • 언어 영어 설정
  • 비쥬얼 스튜디오 버전 설정
  • 에러 리스트 설정 체크 해제
  • solution 툴 길이 200

2. 게임 인스턴스 생성

  • MyGmaeInstance 생성
  • visual studio extension 추가 환경 설정

3. 컴파일 방법

  • 헤더파일에 변경이 발생하면 - 에디터를 끄고 비주얼 스튜디오에서 컴파일한다
  • 소스 파일에만 변경이 발생하면 - 라이브 코딩으로 컴파일한다 (Ctrl+Alt+F11)
  • 비주얼 스튜디오에서 수동으로 클래스를 추가하지 말 것!

4. ⭐상위클래스 사용할 때 지킬것

  • 부모클래스로부터 상속을 받을 때는 Super키워드랑 함수 이름을 꼭 써주는게 언리얼 엔진 코딩에서의 기본
  • 언리얼 엔진이 제공하는 부모 클래스를 상속받아서 가상함수를 override 하여 재구현하는 경우에는 거의 대부분 언리얼 엔진이 미리 작업해준 코드를 실행을 해주어야함
  • 전체 엔진 플로우가 동작할 수 있도록 미리 만들어져있기 때문에 그걸 무시하고 코딩하면 어떤 상황의 문제가 발생할지 모름

5. Log 출력하기

  • UE_LOG(LogTemp, Log, TEXT("%s"), TEXT("Hello Unreal"));
  • 프로젝트 설정에서 Game Instance -> MyGameInstance 로 설정

6. 정리

  • 언리얼 엔진 설치와 프로그래밍 환경 구축
  • 언리얼 에디터에서의 클래스 추가
  • 언리얼 C++의 클래스 상속 및 오버라이딩 구현
  • 언리얼 엔진의 문자열 처리의 이해
  • 게임인스턴스의 클래스 적용과 카테고리를 활용한 로그 확인

👉 실습코드

//MyGameInstance.h
UCLASS()
class HELLOUNREAL_API UMyGameInstance : public UGameInstance
{
	GENERATED_BODY()
public:

	virtual void Init() override;
};

//MyGameInstance.cpp
void UMyGameInstance::Init()
{
	Super::Init();

	UE_LOG(LogTemp, Log, TEXT("%s"), TEXT("Hello Unreal"));
}

2강에서는 언리얼 C++ 코딩 표준에 대해서 학습했습니다. 아래는 필기를 한 강의 노트입니다

📖 2강 필기 노트

코딩표준

  1. public에서 private로 이어지는 클래스 체계(Organization)를 준수
  2. 명명 규칙
    a. 파스칼 케이싱을 사용한다
    b. 소문자를 가급적 사용하지 않고 공백 및 언더스코어(_)가 없음
    c. 모든 클래스와 구조체에는 고유한 접두사가 있음
  3. 코드의 명확성
    a. 파라미터에 가급적 In과 Out 접두사를 사용해 명시
    b. const 지시자(directive)의 적극적인 활용
    c. 레퍼런스를 통한 복사 방지
    d. auto 키워드는 가급적 자제
  4. Find In Files의 활용
  5. 헤더 파일 및 #include 구문은 의존성을 최소화시켜 주의 깊게 다룰 것

👉 언리얼 C++ 코딩표준

3강에서는 언리얼 C++ 기본타입과 문자열에 대해서 공부하고 이를 실습 위주로 학습하였습니다. 아래는 필기를 한 강의 노트입니다

📖 3강 필기 노트

  • 언리얼은 c++ 기본타입을 사용하지 않음
  • int형 변수일때 크기를 확신할 수 없음
  • 후발 언어 C#일 경우 int를 명확히 정의함
  • 언리얼은 int가 아닌 int32를 사용함
📌 게임 제작의 특징
- 데이터 정보가 명확해야 한다 
- 단일 컴퓨터에서 최대 퍼포먼스를 뽑아내야 한다
- 네트웍 상에서 데이터 통신이 효율적이고 안정적이어야 한다
  • TCHAR사용 (고유한 처리 방식)
  • bool 타입 경우에는 크기가 명확하지 않음
  • 헤더에는 가급적 bool 대신 uint8 타입을 사용하되 Bit Field 오퍼레이터를 사용
  • 일반 uint8과 구분을 위해 b접두사를 사용 => 데이터양 최소화
  • 언리얼은 UTF-16을 사용
  • 복잡한 문자열 처리를 하나로
  • 유니코드를 사용해 문자열 처리를 통일 : TCHAR 사용
  • 문자열은 언제나 TEXT매크로 사용해 지정
    - TEXT 매크로로 감싼 문자열은 TCHAR 배열로 지정됨
  • 문자열을 다루는 클래스로 FString을 제공함
    - FString은 TCHAR 배열을 포함하는 헬퍼 클래스
  • FName: 에셋 관리를 위해 사용되는 문자열 체계
    - 대소문자 구분 없음
    - 한번 선언되면 바꿀 수 없음
    - 가볍고 빠름
    - 문자를 표현하는 용도가 아닌 에셋 키를 지정하는 용도로 사용. 빌드시 해시값으로 변환됨
  • FText: 다국어 지원을 위한 문자열 관리 체계
    - 일종의 키로 작용함
    - 별도의 문자열 테이블 정보가 추가로 요구됨
    - 게임 빌드 시 자동으로 다양한 국가별 언어로 변환됨
  • 언리얼은 FName과 관련된 글로벌 Pool 자료구조를 가지고 있음
  • FName과 글로벌 Pool
    - 문자열이 들어오면 해시 값을 추출해 키를 생성해 FName에서 보관
    - FName 값에 저장된 값을 사용해 전역 Pool에서 원하는 자료를 검색해 반환
    - 문자 정보는 대소문자를 구분하지 않고 저장함 (Ignore Case)
  • FName의 형성
    - 생성자에 문자열 정보를 넣으면 풀에 조사해 적당한 키로 변환하는 작업이 수반됨
    - Find or Add

언리얼 C++ 기본 타입과 문자열 처리

  1. 언리얼이 C++ 타입 int를 사용하지 않는 이유
  2. 다양한 캐릭터 인코딩 시스템의 이해
  3. 언리얼의 문자열 처리의 이해
  4. FString의 구조와 사용 방법
  5. FName의 구조와 사용 방법

👉 실습코드

//MyGameInstance.cpp
void UMyGameInstance::Init()
{
	Super::Init();

	//How to use TCHAR
	TCHAR LogCharArray[] = TEXT("Hello Unreal");
	UE_LOG(LogTemp, Log, LogCharArray);

	//How to use FString
	FString LogCharString = LogCharArray;
	UE_LOG(LogTemp, Log, TEXT("%s"), *LogCharString);

	//copy FString (Cant Modify)
	const TCHAR* LongCharPtr = *LogCharString;
	TCHAR* LogCharDataPtr = LogCharString.GetCharArray().GetData();

	//copy FString (Can Modify)
	TCHAR LogCharArrayWithSize[100];
	FCString::Strcpy(LogCharArrayWithSize, LogCharString.Len(), *LogCharString);
	
	//Find and Cut FString
	if (LogCharString.Contains(TEXT("unreal"), ESearchCase::IgnoreCase)) 
	{
		int32 Index = LogCharString.Find(TEXT("unreal"), ESearchCase::IgnoreCase);
		FString EndString = LogCharString.Mid(Index);
		UE_LOG(LogTemp, Log, TEXT("Find Test: %s"), *EndString);
	}

	//Split FString
	FString Left, Right;
	if (LogCharString.Split(TEXT(" "), &Left, &Right))
	{
		UE_LOG(LogTemp, Log, TEXT("Split Test: %s 와 %s"), *Left, *Right);
	}

	//Change Type
	int32 IntValue = 32;
	float FloatValue = 3.141592;

	FString FloatIntString = FString::Printf(TEXT("Int:%d Float:%f"), IntValue, FloatValue);
	FString FloatString = FString::SanitizeFloat(FloatValue);
	FString IntString = FString::FromInt(IntValue);

	UE_LOG(LogTemp, Log, TEXT("%s"), *FloatIntString);
	UE_LOG(LogTemp, Log, TEXT("Int:%s Float:%s"), *IntString, *FloatString);

	int32 IntValueFromString = FCString::Atoi(*IntString);
	float FloatValueFromString = FCString::Atof(*FloatString);
	FString FloatIntString2 = FString::Printf(TEXT("Int:%d Float:%f"), IntValueFromString, FloatValueFromString);
	UE_LOG(LogTemp, Log, TEXT("%s"), *FloatIntString2);

	//Fname Attributes Check
	FName key1(TEXT("PELVIS"));
	FName key2(TEXT("pelvis"));
	UE_LOG(LogTemp, Log, TEXT("FName 비교 결과 : %s"), key1 == key2 ? TEXT("같음") : TEXT("다름"));

	for (int i = 0; i < 10000; ++i) 
	{
		FName SearchInNamePool = FName(TEXT("pelvis"));
		//Tick같은 함수에서 FName을 자주 호출하면 오버헤드 발생 가능성이 있으니 상수로 선언해주기
		const static FName StaticOnlyOnce(TEXT("pelvis"));
	}
}

😅 강의 들으면서 필기한거라 급하게 작성해서 내용이 중구난방일 수 있습니다..!

📌 공부 후기

지난 언리얼 공부에 이어서 언리얼 엔진에 대한 기초 학습을 진행했으니 이제 다음 단계로 넘어가야겠다고 생각을 했다
다음 단계는 이제 언리얼을 활용해서 기초적인 게임을 제작하는 것이고 이를 C++을 활용하여 제작을 해야 했는데
아무래도 기존에 C++개발을 공부하던 서적이 혼자 공부하기엔 아직 좀 이해가 안되어서 강의를 들어야겠다고 생각했다

강의는 인프런에서 강의를 하시는 이득우 강사님의 이득우 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해를 듣게 되었다

이득우님은 원래도 언리얼 엔진 쪽으로 많이 들어본 분이신데 작년에 지원했던 스마일게이트 UNSEEN의 강사였는데 떨어졌어서 좀 아쉬움이 있었다..ㅎ

그외에도 게임 서적을 찾아보곤 하면 많이 봐왔어서 이번에 이득우 강사님의 강의를 듣기로 하였다

현재 0강부터 3강까지 수강하였는데
사실 이런 제대로된 게임개발 수업을 처음 들어보기도 해서 혼자서 독학할때보다 생각보다 자세하고 기초적인 내용을 알려주셔서 흥미롭게 들었다
(C++ 코딩표준, 언리얼 코딩표준 등..)

강의의 내용도 알기쉽게 잘 설명해주실뿐더러 강의 내용의 진행이 실습과 같이 진행되어
뭔가 배우는 내용도 잘 습득이 되는거 같다 아직 배운내용이 얼마없긴 하지만..

확실히 이런 강의를 들어야 기초적인 부분부터 차근차근 쌓아나갈 수 있겠단 생각을 했다

기초부터 착실하게 쌓아나가는 게임개발자가 되어야겠다

profile
게임 개발자 지망생

0개의 댓글