그냥 게임개발자

세번째 - 언리얼 C++ 코딩 표준 본문

Unreal스터디/Unreal압축판

세번째 - 언리얼 C++ 코딩 표준

sudoju 2024. 3. 12. 18:15

저번에 우리는 Hello, World를 언리얼에서 작동 시켜보았다.

 

오늘은 언리얼 프로그래밍을 작성하는데 있어 지켜야 하는 프로그래밍 규치, 작성 방법 등을 지정한 가이드라인에 대해서 알아볼 것이다.

 

위와 같이 이상한 코드는 이해가 잘 가지 않을 것이다. 땀을 왜이렇게 많이 흘ㄹ

 

사실 절대적으로 좋은 코딩 규칙이란 것은 없다.

그냥 내 팀이나 회사에 맞는 코딩 규칙을 지키는 것이 좋다.
중요한 것은 코딩 표준을 정하고 잘 따르는 것이다.

만약 중간에 프로젝트에 참여한다면 그 코드를 리뷰해보고 그 코딩 표준에 맞게 작성하면 된다.
코딩 규칙을 지키는 이유는 같은 팀이 봐도 이해가 갈 코드가 되어야 하기 때문이다.

즉 프로젝트의 모든 코드는 한 사람이 만든 것처럼 보여져야 한다.

 

 

서론이 길었지만 일단 구글 C++ 코딩 표준을 확인해보자.

 

Google C++ Style Guide

 

이 사이트에 들어가보면 여러가지 코딩 규칙의 가이드가 정해져 있다.

 

C++Version은 C++20을 대상으로 사용하고 C++23은 사용하지 말아야 한다 등.

여러가지 규칙이 정해져 있다.

이렇듯 언리얼도 똑같이 언리얼의 맞는 코딩 표준이 정해져있다.

 

 

언리얼 C++ 코딩 표준

 

클래스 체계

클래스는 작성자보다는 읽는 사람을 염두에 두고 만들어져야 한다.

읽는 사람은 대부분 클래스의 퍼블릭 인터페이스를 사용할 것인데, 퍼블릭 인터페이스에서 먼저 선언한 후 클래스의 프라이빗 구현이 뒤따라야 한다.

 

MyGameInstance.h

UCLASS()
class SUDOJUPROJECT_API UMyGameInstance : public UGameInstance
{
	GENERATED_BODY()
};

 

처음 헤더파일에 확인해보면 이런식으로 클래스가 작성이 되어있는 것을 볼 수 있다.

 

이 때 퍼블릭 인터페이스, 프라이빗 구현? 이게 무슨 소리인가 접근 제어자를 뜻한다.

public, protected, private

이 세가지를 말한다.

 

즉 먼저 클래스를 작성할 때 

 

UCLASS()
class SUDOJUPROJECT_API UMyGameInstance : public UGameInstance
{
	GENERATED_BODY()
    
// 아래와 같은 형태로 먼저 작성하고 시작
public:
    
private:

};

이런 식으로 퍼블릭 먼저 그 뒤에는 protected, private 구현이 뒤따라야 한다는 소리이다.

 

저작권 고지

에픽게임즈에서 제공한 모든 소스 파일(.h, .cpp,. xaml, etc.)은 파일 첫 번째 줄에 저작권 고지를 포함해야 한다.
저작권 고지의 포맷은 다음과 정확히 일치해야 한다.

 

모든 소스코드 파일에 이런식으로 작성되어있는 것을 볼 수가 있다.

하지만 다른 에픽게임 소스코드를 살펴보면

이런식으로 작성이 되어있는 것을 확인할 수 있다.

이것을 수정하는 방법은 간단하다.

물론 직접 작성해도 되지만 다른 방식이 있다.

 

프로젝트 세팅에 들어가서

 

빨간 네모칸 안에 글들을 수정해주면 모든 소스코드가 작성이 될 때 수정이 된다.

 

프로그래밍 언어의 명명 규칙

파스칼 케이싱(Pascal Casing) : 합성어의 첫 글자를 대문자를 사용해 명명
ex) UnrealEngine
카멜(낙타) 케이싱(Camel Casing) : 첫 합성어는 솜누자로 나머지는 대문자를 사용해 명명
ex) unrealEngine
스네이크 케이싱(Snake Casing) : 합성어 사이에 언더바(_)를 사용해 명명
ex) unreal_engine

 

언리얼 엔진은 기본적으로 파스칼 케이싱을 사용하지만 여기에 더추가가 되는 것들이 있다.

 

  • 템플릿 클래스에는 접두사 T를 포함
  • UObject에서 상속받는 클래스에는 접두사 U를 포함
  • AActor에서 상속받는 클래스에는 접두사 A를 포함
  • SWidget에서 상속받는 클래스에는 접두사 S를 포함
  • 추상적 인터페이스인 클래스에는 접두사 I를 포함
  • 열거형에는 접두사 E를 포함
  • 부울 변수는 접두사 b를 포함 (예 : bPendingDestruction또는 bHasFadedIn)
  • 그 외 대부분의 클래스는 접두사 F를 포함
  • Typedef의 경우 해당 타입에 적합한 접두사를 사용. 예를 들어 구조체의 typedef인 경우 F, UObjecttypedef인 경우 U를 사용

뭐가 이렇게 많나 싶지만. 사실 지금 이걸 봐도 이해가 안가도 무방하다.

 

나중에 많이 사용하다가 어 이거 왜 이렇게썼지?

할 때 다시 보면 된다.

그러면 이해가 갈것이니 AActor는 뭐고 SWidget은 뭐고 이런거는 그냥 있다고만 생각하자.

 

사실 이것보다 더 많은 규칙이 많다.

 

처음부터 너무 많은 것을 알게되면 좋지만, 재미가 없어지면 말짱 꽝이다.

 

나는 당장 지금 알고싶어!!

하면 좀 참아주라..

 

 

표준 라이브러리 사용

C++은 STL(Standard Template Library)라이브러리를 사용한다.

 

언리얼이 만들어져 있을 당시에는 STL라이브러리가 있지는 않았다.

그래서 언리얼 자체적으로 멀티 플랫폼에서 안정적으로 동작하는 표준 라이브러리를 에픽게임즈가 그냥 직접 구축했단다.

 

즉, C++ 표준 라이브러리를 사용하지 않는다가 기본 원칙이다.

 

Const 정확도

Const 뭐냐 상수다.

에잉 이거 모르면

 

다시 언어부터 공부하자.

 

언리얼에서 강조하는 것은 가급적이면 모든 코드는 const를 쓰자라는 규칙이다.

 

사실 뭐 되게 많다 규칙은 

하지만 규칙은 내가 만들어가는거다.

 

규칙은 깨라고 있는거야.

 

사실 언리얼 예제코드를 많이 보면 다 규칙을 잘사용해 하고 있기 때문에 언리얼 예제코드를 많이 봐보자.

 

정리하자면 이렇다.

  1. public에서 private로 이어지는 클레스 체계(Organization)를 준수하자!
  2. 명명 규칙
    • 파스칼 케이싱(Pascal Casing)을 사용하자
    • 소문자를 가급적 사용하지 않고 공백 및 언더바(_)가 없다
    • 모든 클래스와 구조체에는 고유한 접두사가 있다 U, A, F 등
  3. 코드의 명확성
    • 파라미터에 가급적 In과 Out 접두사를 사용해 명시하자.
    • const 지시자(Directive)의 적극적으로 활용하자.
    • 레퍼런스를 통한 복사 방지
    • auto 키워드는 가급적 자제 (유니티에선 var)
  4. 헤더 파일 및 #include 구문은 의존성을 최소화 시켜 주의 깊게 다루자.

 

이해했죠?

 

괜찮아요 저도 위 그림처럼 살고 있었어요.

 

근데 이게 언리얼 코드를 작성하다보면 이해가 되더라구요 조금만 참읍시다.