Unreal C++ 코딩 표준

Lee Raccoon·2024년 5월 10일
0

언리얼 공부

목록 보기
1/11

코딩 표준이란?

프로젝트는 다른 사람과 함께 하게 된다.
이 때 다른 사람과 코드를 작성하는 스타일이 많이 다르다면 서로 작성한 코드를 볼 때 가독성이 떨어지게 된다.
그렇기 때문에 마치 한 사람이 작성한 것 처럼 모든 코드 스타일이 동일한 것이 가장 좋다.
규모 있는 프로젝트는 코딩 표준, 스타일 가이드를 정하여 많은 사람들의 스타일을 하나로 통일시킨다.
언리얼은 자체적으로 표준이 존재하기 때문에, 이를 따르는 것이 좋다.

Unreal 코딩 표준

이 중 중요하다고 생각하는 몇가지를 정리해보았다.

클래스 체계

  • 대부분의 사용자들은 클래스의 퍼블릭 인터페이스를 사용할 것이므로 퍼블릭 구현을 먼저 선언하여 가독성을 높여야 한다.

저작권 고지

  • 공개 배포용으로 에픽에서 제공한 모든 소스 파일(.h , .cpp , .xaml )은 파일 첫 번째 줄에 저작권 고지를 포함해야 합니다. 저작권 고지의 포맷은 다음과 정확히 일치해야 합니다.

명명 규칙

  • 언리얼 엔진은 PascalCase 포맷을 사용한다.
    (PascalCase은 단어의 첫글자를 대문자로 쓰는 형식)

  • 대문자로 접두사를 붙여서 타입 이름과 변수 이름을 구분한다.

    • Template -> T
      UObject → U
      AAcotr → A
      SWidget → S
      Interface → I
      Enum → E
      bool → b
      그 외 대부분 → F
    • Typedef는 구조체의 경우 F, UObject인 경우 U
    • 템플릿의 인스턴스화의 typedef는 더 이상 템플릿이 아니므로 알맞은 접두사를 붙여야 함
    • C#에서는 접두사 생략.
  • 타입 및 변수 이름은 명사이다.

  • 메서드 이름은 메서드를 설명하는 동사이다.

  • 이름은 명확하고 확실하고 내용을 파악할 수 있어야한다.

  • bool을 반환하는 함수는 질문 형식이어야 한다.

  • 함수 파라미터가 레퍼런스인 경우, 함수를 그 값에 쓸 것으로 예상되는 경우 Out을 붙이는 것이 좋다.

  • 또한 항상 정중하고 포용성있는 단어를 사용하며 이중적 의미가 있는 단어를 피해야한다.

표준 라이브러리 사용

동일한 API에서 표준 라이브러리와 UE 언어를 아래와 같은 이유로 혼용하지 않도록 해야한다.

  • 비표준 동작 변경 수행
  • 전체적 문법 일관성 유지
  • UE 언어와 호환되지 않는 컨스트럭트 방지

Const 정확도

모든 코드는 Const 정확도를 맞추어야 한다.

  • 함수 실행인자가 함수에 의해 수정되지 않아 이를 const 포인터 혹은 참조로 전달하는 경우
  • 메서드가 오브젝트를 수정하지 않아 const로 메서드의 플래그를 지정하는 경우
  • 루프에서 컨테이너 수정을 하지 않아 const를 사용하여 컨테이너에 반복작업을 하는 경우

하지만 값에 의한 전달 파라미터는 예외로 한다.

Nullptr

C 스타일 NULL 매크로가 아닌 nullptr을 사용해야 한다.

Auto

auto 를 사용 가능한 경우는 다음과 같다.

  • 변수에 람다를 바인딩해야 하는 경우. 람다 타입은 코드로 표현할 수 없기 때문이다.
  • 이터레이터 변수의 경우. 단, 이터레이터 타입이 매우 장황하여 가독성에 악영향을 미치는 경우에 한함
  • 템플릿 코드에서 표현식의 타입을 쉽게 식별할 수 없는 경우. 고급 사용 사례이다.

이외에는 Auto 사용을 지양해야한다.

범위 기반 For

가독성을 위해 새 스타일의 사용을 추천한다.

	TMap<FString, int32> MyMap;
    
    // 기존 스타일
    for (auto It = MyMap.CreateIterator(); It; ++It)
    {
        UE_LOG(LogCategory, Log, TEXT("Key: %s, Value: %d"), It.Key(), *It.Value());
    }
    
    // 새 스타일
    for (TPair<FString, int32>& Kvp : MyMap)
    {
        UE_LOG(LogCategory, Log, TEXT("Key: %s, Value: %d"), *Kvp.Key, Kvp.Value);
    }

기타

  • 파일 끝에 빈 줄 하나를 만들어야 한다.
    모든 .cpp 및 .h 파일은 빈 줄이 있어야 gcc와 함께 제대로 작동한다.

  • 섀도잉 된 변수는 허용하지 않는다.

  • 종속성 거리를 최소화 시켜야한다.
    코드가 특정 값에 의존할 때, 변수를 사용하기 직전에 그 값을 설정하는 것이 좋다.

  • 익명 리터럴로 함수 사용은 피해야한다.

		  // 기존 스타일
          Trigger(TEXT("Soldier"), 5, true);.
            
          // 새 스타일
          const FName ObjectName                = TEXT("Soldier");
          const float CooldownInSeconds         = 5;
          const bool bVulnerableDuringCooldown  = true;
          Trigger(ObjectName, CooldownInSeconds, bVulnerableDuringCooldown);
  • 헤더에 특수한 스태틱 변수를 정의하지 않아야 한다.
    특수한 스태틱 변수는 해당 헤더가 포함된 이동 단위마다 인스턴스를 컴파일한다.
// SomeModule.h
          static const FString GUsefulNamedString = TEXT("String");
 
  //이러한 코드는 다음으로 대체해야 함
 
          // SomeModule.h
          extern SOMEMODULE_API const FString GUsefulNamedString;
 
          // SomeModule.cpp
          const FString GUsefulNamedString = TEXT("String");
  • bool과 FString은 함수 오버로드를 하지 말아야한다.
    둘 중 어떤 것이 호출될지 예상할 수 없게 된다.

  • bool 타입을 선언 할 때, uin32 b변수명:1 로 선언해서 bool 타입의 크기를 명확하게 해주어야한다.

profile
영차 영차

0개의 댓글