[GroupProject_AOW]#1. UE 5.2ver Coding Convention, 24/09/22 Updated

2024. 4. 8. 20:18· 그룹프로젝트/PM
목차
  1. #1. 코딩 컨밴션
  2. 1. 개념
  3. 2. 장점, 왜 필요한가? 
  4. 3. 코드 컨밴션 확립 방법 및 과정
  5. #2. 가이드라인
  6. 1. 명명 방법 및 기본 세팅 관련 커스텀 규칙
  7. 2. 클래스 관련 규칙
  8. 2. 예제
  9. 3. 그 외 규칙
  10.  

 

#1. 코딩 컨밴션

 

1. 개념

 

코딩 컨밴션은 특정 프로그래밍 언어나 프로젝트, 팀에서 코드를 어떻게 작성할지에 대한 규칙이나 가이드라인을 의미합니다. 이는 변수명, 함수명의 명명 법, 들여 쓰기의 크기, 코드 라인의 길이, 주석의 방법 등 다양한 측면을 포함할 수 있습니다.

 

2. 장점, 왜 필요한가? 

 

코드 컨밴션을 통해 그룹 내 협업 과정에서 일관된 코드 스타일을 유지할 수 있도록 해줍니다. 이를 통해, 기존 코드의 확장 혹은 수정 작업이 용이해지며, 원활한 코드 리뷰가 가능해집니다. 정리하면, 코드 컨밴션은 코드의 일관성을 유지할 수 있도록 도와주며, 이는 코드의 가독성과 유지보수성 향상에 기여합니다. 이를 통해, 그룹 내 협업이 효율적으로 이루어집니다.

 

3. 코드 컨밴션 확립 방법 및 과정

 

  1. 가이드라인 선정 : Unreal에서 제공하는 기존의 코드 컨밴션을 기반으로 팀 특성에 맞는 커스텀 규칙을 정합니다.
  2. 문서 작성 : 결정된 코드 컨밴션은 모든 팀원이 접근할 수 있는 문서로 작성하며, 해당 문서는 프로젝트 진행 과정에서 지속적으로 업데이트합니다.
  3. 코드 리뷰 : 정기적으로 코드 리뷰를 실시하여, 코드 컨밴션 준수 여부를 확인하고 피드백을 서로에게 제공합니다. 

 


 

#2. 가이드라인

 

1. 명명 방법 및 기본 세팅 관련 커스텀 규칙

 

1. #include

// 0. 헤더 파일은 최소화, 필요 없는 헤더 파일은 제거

#include "GameFramework/CharacterMovementComponent.h" // 제거!
#include "04_Component/BaseCharacterMovementComponent.h" // 해당 헤더파일에서 이미 위 헤더파일을 #include 하고 있음

// 1. .h 파일 상단에 #pragma once 작성 (중복 #include를 방지)

#pragma once

// 2. 내부 파일 헤더 및 Log 관련 헤더를 먼저 입력

#include "PlayerCharacter.h"
#include "Logging/StructuredLog.h"

// 3. 관련 내용 끼리 묶어 놓고, 각 묶음을 개행으로 구분

#include "04_Component/BaseInputComponent.h" // 해당 클래스의 Default Coomponent들
#include "04_Component/BaseCharacterMovementComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Components/CapsuleComponent.h"
#include "Camera/CameraComponent.h"

#include "03_Player/BasePlayerController.h" // 해당 클래스의 함수 본문에서 활용하는 클래스들
#include "03_Player/PlayerStateBase.h"
#include "04_Component/BaseAbilitySystemComponent.h"

#include "Kismet/KismetMathLibrary.h" // Math 관련 라이브러리

 

2. 변수 명명 규칙

// 1. Pascal Case 활용 : 각 단어를 대문자로 구분하는 명명 방법

int SomeInt = 3;
int CurrentInt = 4;

// 2. bool 형은 접두어 'b' 붙이기

bool bFalling = false;
bool bMoving = false;

// 3. float 형은 정수의 소수점 뒤 접미어 'f'붙이기

float SomeFloat = 3.f;
float SomeFloat2 = 2.5f;

// 4. 열거형은 접두어 'E' 붙이기

enum class EPlayerState : uint8
{
//...
};

enum class EMovementState : uint8
{
//...
};

// 5. 구조체는 접두어 'F' 붙이기

struct FBaseAbilitySet
{
//...
};

 

3. 함수 명명 규칙

// 1. Pascal Case & 동사+목적어 조합 : 함수 명명 규칙 및 인자(Param)에도 동일하게 적용.

UCLASS()
class AGEOFWOLVES_API UInputConfig : public UDataAsset
{
//...
    UFUNCTION(BlueprintCallable, Category = "Input | Input Action")
	const UInputAction* FindNativeInputActionForTag(const FGameplayTag& InputTag, bool bLogNotFound = true) const;

    UFUNCTION(BlueprintCallable, Category = "Input | Input Action")
	const UInputAction* FindAbilityInputActionForTag(const FGameplayTag& InputTag, bool bLogNotFound = true) const;
//...
}

// 2. Out Parameter의 경우 인자명 앞에 접두어 'Out' 붙여주기

UCLASS()
class AGEOFWOLVES_API UBaseAbilitySet : public UPrimaryDataAsset
{
//...
    void GiveStartupAttributeSetToAbilitySystem(UBaseAbilitySystemComponent* ASC, FBaseAbilitySet_GrantedHandles* OutGrantedHandles, UObject* SourceObject) const;
//...
};

// 3. 이벤트(Delegate) 타입은 접두어 'F'를 붙여주고, 선언 시 'On'을 붙여준다.

DECLARE_DYNAMIC_DELEGATE(FPlayerInputInit); // 'F + ~' 조합

class SomeClass
{
public:
    FPlayerInit OnPlayerInit // 'On + ~' 조합
};

// 4. Template 함수의 경우 클래스 내부에서 선언과 정의를 함께 작성

class SomeClass
{
//...
    // @brief : Tempalte function in which Native Input Action matching to the Input Tag will bind to User's Callback Function
    template<typename UserClass, typename FuncType>
    void BindNativeInputAction(const UInputConfig* InputConfig, const FGameplayTag& InputTag, ETriggerEvent TriggerEvent, UserClass* Object, FuncType Func)
    {
    	check(InputConfig);

    	if (const auto& InputAction = InputConfig->FindNativeInputActionForTag(InputTag))
    	{
    		BindAction(InputAction, TriggerEvent, Object, Func);
    	}
    }
};

// 5. 지역 변수는 사용처와 최대한 가까운 곳에 정의, 최대한 늦게 정의

void APlayerCharacter::AdjustControllerRotation(float DeltaSeconds)
{

    check(DirectionCurve);

    // 캐릭터의 현재 가속도 벡터를 기반으로 한 로테이션을 계산
    FRotator Rotation1 = UKismetMathLibrary::MakeRotFromX(GetCharacterMovement()->GetCurrentAcceleration());

    // 캐릭터가 바라보는 방향의 벡터를 기반으로 로테이션을 계산
    FRotator Rotation2 = GetControlRotation();

    // 두 방향 사이의 최소 각도 차이를 계산
    float OffsetAngle = DirectionCurve->GetFloatValue(FMath::FindDeltaAngleDegrees(Rotation1.Yaw, Rotation2.Yaw));

    FRotator Rotaion3 = UKismetMathLibrary::MakeRotator(0.f, 0.f, GetControlRotation().Yaw + OffsetAngle);

    // 선형 보간
    FRotator TargetRotation = UKismetMathLibrary::RInterpTo(GetActorRotation(), Rotaion3, DeltaSeconds, 10.f);

    SetActorRotation(TargetRotation);

}

 

4. 주석 작성 규칙

// 1. [ @목적, @설명, @참조 ] 기본 구조, 목적과 설명은 필수, 참조는 선택

#pragma region Controller Rotaion
protected:
    /*
    * @목적 : 캐릭터 객체의 회전 값을 Controller의 회전 값에 따른 보간 작업을 수행합니다.
    * @설명 : 사용자 카메라가 바라보는 방향과 캐릭터 객체가 바라보는 방향의 조정 작업을 수행합니다.
    * @참조 : -
    */ 
    void AdjustControllerRotation(float DeltaSeconds);

    /*
    * @목적 : 사용자의 카메라 회전에 따른 캐릭터 객체의 회전 보간 작업
    * @설명 : Float Curve를 통해 카메라(Controller) 회전 값과 캐릭터 이동 방향의 회전 값
    * @참조 : APlayerCharacter::AdjustControllerRotation
    */
    UPROPERTY(EditDefaultsOnly, Category = "Character Movement|Control Rotation")
    	UCurveFloat* DirectionCurve;
#pragma endregion

 

2. 클래스 관련 규칙

 

1. 헤더 파일(. h) 구조

//@#include

//@UE_LOGFMT 활용을 위한 로그 매크로 선언

//@전방 선언
#pragma region Forward Declaration
#pragma endregion

//@열거형
#pragma region Enums
#pragma endregion

//@구조체
#pragma region Structs
#pragma endregion

//@이벤트/델리게이트
#pragma region Delegates
#pragma endregion

class MyClass
{
//@친추 클래스
#pragma region Friend Class
#pragma endregion

GENERATED_BODY()

//@Defualt Setting
#pragma region Default Setting
#pragma endregion

//@Property/Info...etc
#pragma region Property or Subwidgets or Infos...etc
#pragma endregion

//@Delegates
#pragma region Delegates
#pragma endregion

//@Callbacks
#pragma region Callbacks
#pragma endregion

//@Utility(Setter, Getter,...etc)
#pragma region Utility
#pragma endregion

};

 

  1. #include 작성,. generated.h 라인 위로 개행 추가. 해당 라인 아래로 #include 작성을 예방.
  2. 전방 선언
  3. 열거형
  4. 구조체
  5. 이벤트/델리게이트
  6. Friend Class: 친구 클래스
  7. Default Setting: 생성자, 인터페이스 함수 등
    1. 인터페이스
    2. 외부 바인딩
    3. 내부 바인딩
    4. 초기화
    5. 초기화 완료 체크
  8. Properties, Infos...etc: 데이터 멤버 등
  9. Delegates
  10. Callbacks
  11. Utilities: Getter, Setter, 등등

 

2. 예제

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"

#include "ConfirmationMenu.generated.h"

DECLARE_LOG_CATEGORY_EXTERN(LogConfirmationMenu, Log, All)

//@전방 선언
#pragma region Forward Declaration
class UOverlay;
class UHorizontalBox;
class UImage;
class UCustomButton;
#pragma endregion

//@열거형
#pragma region Enums
#pragma endregion

//@구조체
#pragma region Structs
#pragma endregion

//@이벤트/델리게이트
#pragma region Delegates
//@초기화 완료 이벤트
DECLARE_DELEGATE(FConfirmationMenuInitFinished);

//@Confirmation Menu 버튼 선택 이벤트
DECLARE_DELEGATE_OneParam(FConfirmationMenuButtonClicked, FName);
//@확정 메뉴  버튼 호버 이벤트
DECLARE_MULTICAST_DELEGATE_OneParam(FConfirmationMenuButtonHovered, FName)
//@확정 메뉴  버튼 언호버 이벤트
DECLARE_MULTICAST_DELEGATE_OneParam(FConfirmationMenuButtonUnhovered, FName)

//@선택된 확정 메뉴 버튼 선택 취소 이벤트
DECLARE_MULTICAST_DELEGATE(FNotifyConfirmationMenuButtonCanceled);
#pragma endregion

/**
 * @UConfirmationMenu
 * 
 * 사용자 지시의 최종 확정을 위한 UI
 */
UCLASS()
class AGEOFWOLVES_API UConfirmationMenu : public UUserWidget
{
//@친추 클래스
#pragma region Friend Class
#pragma endregion

	GENERATED_BODY()
	
//@Defualt Setting
#pragma region Default Setting
public:
    UConfirmationMenu(const FObjectInitializer& ObjectInitializer);

protected:
    //~ Begin UUserWidget Interfaces
    virtual void NativeOnInitialized() override;
    virtual void NativePreConstruct() override;
    virtual void NativeConstruct() override;
    virtual void NativeDestruct() override;
    //~ End UUserWidget Interface

protected:
    //@외부 바인딩

protected:
    //@내부 바인딩
    void InternalBindToButton(UCustomButton* Button, FName OptionName);

protected:
    //@초기화
    UFUNCTION()
        virtual void InitializeConfirmationMenu();
#pragma endregion

//@Property/Info...etc
#pragma region Property or Subwidgets or Infos...etc
protected:
    virtual void CreateButton();

protected:
    //@Overlay
    UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
        UOverlay* ConfirmationMenuOverlay;

protected:
    //@배경 이미지
    UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
        UImage* ConfirmationMenuBGImage;

protected:
    //@가로 박스
    UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
        UHorizontalBox* ConfirmationMenuButtonBox;

protected:
    //@현재 선택된 확정 옵션(OK or CANCEL)
    TWeakObjectPtr<UCustomButton> CurrentSelectedConfirmationOption;
    //@TMap
    TMap<FName, TObjectPtr<UCustomButton>> MConfirmationButtons;
    //@Custom Button Class
    UPROPERTY(EditDefaultsOnly, category = "Coonfirmation Menu | Button")
        TSubclassOf<UCustomButton> ConfirmationMenuButtonClass;
#pragma endregion

//@Delegates
#pragma region Delegates
public:
    //@초기화 완료 이벤트
    FConfirmationMenuInitFinished ConfirmationMenuInitFinished;

public:
    //@확정 메뉴 버튼 Click 이벤트
    FConfirmationMenuButtonClicked ConfirmationMenuButtonClicked;
    //@확정 메뉴 버튼  Hoer 이벤트
    FConfirmationMenuButtonHovered ConfirmationMenuButtonHovered;
    //@확정 메뉴 버튼 Unhover 이벤트
    FConfirmationMenuButtonUnhovered ConfirmationMenuButtonUnhovered;

public:
    //@확정 메뉴 버튼 선택 취소 알림 이벤트
    FNotifyConfirmationMenuButtonCanceled NotifyConfirmationMenuButtonCanceled;

#pragma endregion

//@Callbacks
#pragma region Callbacks
protected:
    //@Inventory Tool Bar 버튼 클릭 이벤트 구독
    UFUNCTION(BlueprintNativeEvent)
        void OnConfirmationMenuButtonClicked(FName OptionName);
    virtual void OnConfirmationMenuButtonClicked_Implementation(FName OptionName) {}
    //@Inventory Tool Bar 버튼 Hover 이벤트 구독
    UFUNCTION(BlueprintNativeEvent)
        void OnConfirmationMenuButtonHovered(FName OptionName);
    virtual void OnConfirmationMenuButtonHovered_Implementation(FName OptionName) {}
    //@Inventory Tool Bar 버튼 Unhover 이벤트 구독
    UFUNCTION(BlueprintNativeEvent)
        void OnConfirmationMenuButtonUnhovered(FName OptionName);
    virtual void OnConfirmationMenuButtonUnhovered_Implementation(FName OptionName) {}

protected:
    //@Inventory Tool Bar 버튼 선택 취소 이벤트 구독
    UFUNCTION(BlueprintNativeEvent)
        void CancelConfirmationMenuButtonSelected(FName PreviousOptionName);
    virtual void CancelConfirmationMenuButtonSelected_Implementation(FName PreviousOptionName) {}
#pragma endregion

//@Utility(Setter, Getter,...etc)
#pragma region Utility
#pragma endregion

};

 

3. 그 외 규칙

// 1. 클래스의 데이터 멤버에 직접적으로 접근하지 않습니다! 꼭, Getter&Setter 활용

FORCEINLINE float GetRotationRate() { return RotationRate; };

// 앞으로 추가될 내용 아래 작성

 


 

 

 

 

 

저작자표시 (새창열림)

'그룹프로젝트 > PM' 카테고리의 다른 글

[GroupProject_AOW]#2. GitHub Policy  (0) 2024.04.09
  1. #1. 코딩 컨밴션
  2. 1. 개념
  3. 2. 장점, 왜 필요한가? 
  4. 3. 코드 컨밴션 확립 방법 및 과정
  5. #2. 가이드라인
  6. 1. 명명 방법 및 기본 세팅 관련 커스텀 규칙
  7. 2. 클래스 관련 규칙
  8. 2. 예제
  9. 3. 그 외 규칙
  10.  
'그룹프로젝트/PM' 카테고리의 다른 글
  • [GroupProject_AOW]#2. GitHub Policy
Hardii2
Hardii2
Hardii2
개발 블로그
Hardii2
전체
오늘
어제
  • 분류 전체보기
    • 알고리즘
    • 웹 개발
      • Node.js
      • React
    • 게임개발
      • DirectX12
      • 관련 지식
      • Unreal C++
      • Unreal 블루프린트
    • 언어
      • Effective C++
      • Basic C++
      • 디자인 패턴
      • 자료구조
      • 기술 질문
    • 문제 풀이
      • BOJ 문제 풀이
      • Programmers 문제 풀이
      • geeksForgeeks 문제 풀이
    • 수학
      • 확률과 통계
      • 게임수학
    • 개인프로젝트
    • 그룹프로젝트
      • PM
      • Dev
    • Github

블로그 메뉴

  • 홈
  • 글쓰기

공지사항

인기 글

태그

  • BFS
  • set
  • 알고리즘
  • DP
  • unreal
  • 기술 질문
  • programmers
  • 디자인 패턴
  • 개발
  • 정렬
  • C++
  • Effective C++
  • dfs
  • 그래프
  • 최단 경로
  • 트리
  • 우선순위 큐
  • Unreal Blueprint
  • BOJ
  • stl

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
Hardii2
[GroupProject_AOW]#1. UE 5.2ver Coding Convention, 24/09/22 Updated
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.