원문링크 : https://docs.unrealengine.com/latest/INT/Programming/Development/CodingStandard/
Coding Standard
At Epic, we have a few simple coding standards and conventions. This document is not meant to be a discussion or work in progress, but rather, reflects the state of Epic's current coding standards.
Code conventions are important to programmers for a number of reasons :
80% of the lifetime cost of a piece of software goes to maintenance.
Hardly any software is maintained for its whole life by the original author.
Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly.
If we decide to expose source code to mod community developers, we want it to be easily understood.
Many of these conventions are actually required for cross-compiler compatibility.
The coding standards below are C++-centric, but the spirit of the standards are expected to be followed no matter which language is used. A section may provide equivalent rules or exceptions for specific languages where it's applicable.
Class Organization
Classes should be organized with the reader in mind rather than the writer. Since most readers will be using the public interface of the class, that should be declared first, followed by the class's private implementation.
Copyright Notice
Any source file (.h, .cpp, .xaml, etc.) provided by Epic for distribution must contain a copyright notice as the first line in the file. The format of the notice must exactly match that shown below:
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
If this line is missing or not formatted properly, CIS will generate an error and fail.
Naming Conventions
The first letter of each word in a name (e.g. type or variable) is capitalized, and there is usually no underscore between words. For example, Health and UPrimitiveComponent, but not lastMouseCoordinates or delta_coordinates.
Type names are prefixed with an additional upper-case letter to distinguish them from variable names. For example, FSkin is a type name, and Skin is an instance of a FSkin.
형식 이름에는 변수 이름과 구별하기 위해 접두사가 추가로 붙습니다. 예를 들어, FSkin은 형식 이름이고 Skin은 FSkin의 인스턴스입니다.
Template classes are prefixed by T.
템플릿 클래스 앞에는 T가 붙습니다.
Classes that inherit from UObject are prefixed by U.
- UObject로부터 상속받은 클래스 앞에는 U가 붙습니다.
Classes that inherit from AActor are prefixed by A.
- Actor로부터 상속받은 클래스는 접두사 A로 시작됩니다.
Classes that inherit from SWidget are prefixed by S.
- SWidget에서 상속받은 클래스 앞에는 S가 붙습니다.
Classes that are abstract interfaces are prefixed by I.
- 추상 인터페이스 인 클래스에는 I가 접두사로 붙습니다.
Enums are prefixed by E.
- 토글형은 접두사가 E입니다.
Boolean variables must be prefixed by b (e.g. "bPendingDestruction", or "bHasFadedIn").
- 불린변수(true or false) 앞에는 b가 있어야합니다 (예 : "bPendingDestruction"또는 "bHasFadedIn").
Most other classes are prefixed by F, though some subsystems use other letters.
- 일부 하위 시스템은 다른 문자를 사용하지만 대부분의 다른 클래스는 접두사 F가 붙습니다.
Typedefs should be prefixed by whatever is appropriate for that type: F if it's a typedef of a struct, U if it's a typedef of a UObject etc.
typedef는 그 타입에 적절한 접두어를 붙여야합니다 : F는 구조체의 typedef이면, U는 UObject 등의 typedef 인 경우 U입니다.
A typedef of a particular template instantiation is no longer a template and should be prefixed accordingly, e.g.:
- 특정 템플릿 인스턴스화의 typedef는 더 이상 템플릿이 아니며 접두어로 사용해야합니다 (예 :
typedef TArray<FMyType> FArrayOfMyTypes;
Prefixes are omitted in C#.
- 접두사는 C #에서 생략됩니다.
UnrealHeaderTool requires the correct prefixes in most cases, so it's important to provide them.
- UnrealHeaderTool은 대부분의 경우 올바른 접두어를 필요로하므로이를 제공하는 것이 중요합니다.
Variable, method, and class names should be clear, unambiguous, and
descriptive. The greater the scope of the name, the greater the
importance of a good, descriptive name. Avoid over-abbreviation.
변수, 메소드 및 클래스 이름은 분명하고 모호하지 않으며 설명이 있어야합니다. 이름의 범위가 클수록 우수하고 설명이 포함 된 이름의 중요성이 커집니다. 지나치게 약어를 사용하지 마십시오.
All variables should be declared one at a time so that a comment
on the meaning of the variable can be provided. Also, the JavaDocs style
requires it. You can use multi-line or single line comments before a
variable, and the blank line is optional for grouping variables.
모든 변수는 변수의 의미에 대한 설명을 제공 할 수 있도록 한 번에 하나씩 선언해야합니다. 또한 JavaDocs 스타일을
요구합니다. 변수 앞에 여러 줄 또는 한 줄 주석을 사용할 수 있으며 변수를 그룹화 할 때는 빈 줄을 선택적으로 사용할 수
있습니다.
All functions that return a bool should ask a true/false question, such as IsVisible() or ShouldClearBuffer().
bool을 반환하는 모든 함수는 IsVisible () 또는 ShouldClearBuffer ()와 같은 true / false 질문을 요청해야합니다.
A procedure (a function with no return value) should use a strong
verb followed by an Object. An exception is if the Object of the method
is the Object it is in; then the Object is understood from context.
Names to avoid include those beginning with "Handle" and "Process"; the
verbs are ambiguous.
프로시저(반환 값이없는 함수)는 강력한 동사 다음에 Object를 사용해야합니다. 메소드의 Object가
Object 인 경우는 예외입니다. 그 객체는 문맥으로부터 이해된다. 피해야 할 이름에는 "Handle"및 "Process"로
시작하는 이름이 포함됩니다 ; 동사는 모호합니다..
Though not required, we encourage you to prefix function
parameter names with "Out" if they are passed by reference and the
function is expected to write to that value. This makes it obvious that
the value passed in this argument will be replaced by the function.
필수 사항은 아니지만 참조로 전달되고 함수가 해당 값을 쓸 것으로 예상되는 경우 함수 매개 변수 이름 앞에 "Out"을 붙이는 것이 좋습니다. 이것은이 인수에서 전달 된 값이 함수로 대체된다는 것을 분명하게합니다.
If an In or Out parameter is also a boolean, put the b before the In/Out prefix, e.g. "bOutResult".
In 또는 Out 매개 변수도 부울 값이면 In / Out 접두사 앞에 b를 넣습니다. "bOutResult".
Functions that return a value should describe the return value; the name should make clear what value the function will return. This is particularly important for boolean functions. Consider the following two example methods:
값을 반환하는 함수는 반환 값을 설명해야합니다. 이름은 함수가 반환 할 값을 분명히해야합니다. 이는 부울 함수에 특히 중요합니다. 다음 두 가지 예제 메서드를 고려하십시오.
bool CheckTea(FTea Tea) {...} // what does true mean?
bool IsTeaFresh(FTea Tea) {...} // name makes it clear true means tea is fresh
Examples
float TeaWeight;
int32 TeaCount;
bool bDoesTeaStink;
FName TeaName;
FString TeaFriendlyName;
UClass* TeaClass;
USoundCue* TeaSound;
UTexture* TeaTexture;
Portable Aliases for Basic C++ Types
bool for boolean values (NEVER assume the size of bool). BOOL will not compile.
TCHAR for a character (NEVER assume the size of TCHAR).
uint8 for unsigned bytes (1 byte).
int8 for signed bytes (1 byte).
uint16 for unsigned "shorts" (2 bytes).
int16 for signed "shorts" (2 bytes).
uint32 for unsigned ints (4 bytes).
int32 for signed ints (4 bytes).
uint64 for unsigned "quad words" (8 bytes).
int64 for signed "quad words" (8 bytes).
float for single precision floating point (4 bytes).
double for double precision floating point (8 bytes).
PTRINT for an integer that may hold a pointer (NEVER assume the size of PTRINT).
Use of C++'s int and unsigned int types - whose size may vary across platforms - is acceptable in code where the integer width is unimportant. Explicitly-sized types must still be used in serialized or replicated formats.
Comments
Comments are communication; communication is vital. Some things to keep in mind about comments (from Kernighan & Pike The Practice of Programming):
Guidelines
Write self-documenting code:
// Bad:
t = s + l - b;
// Good:
TotalLeaves = SmallLeaves + LargeLeaves - SmallAndLargeLeaves;
Write useful comments:
// Bad:
// increment Leaves
++Leaves;
// Good:
// we know there is another tea leaf
++Leaves;
Do not comment bad code - rewrite it:
// Bad:
// total number of leaves is sum of
// small and large leaves less the
// number of leaves that are both
t = s + l - b;
// Good:
TotalLeaves = SmallLeaves + LargeLeaves - SmallAndLargeLeaves;
Do not contradict the code:
// Bad:
// never increment Leaves!
++Leaves;
// Good:
// we know there is another tea leaf
++Leaves;
Const correctness
const is documentation as much as it is a compiler directive, so all code should strive to be const-correct.
This includes passing function arguments by const pointer or reference if those arguments are not intended to be modified by the function, flagging methods as const if they do not modify the object, and using const iteration over containers if the loop isn't intended to modify the container.
void SomeMutatingOperation(FThing& OutResult, const TArray<int32>& InArray); // InArray will not be modified by SomeMutatingOperation, but OutResult probably will be
void FThing::SomeNonMutatingOperation() const
{
// This code will not modify the FThing it is invoked on
}
TArray<FString> StringArray;
for (const FString& : StringArray)
{
// The body of this loop will not modify StringArray
}
'Technical Report > Unreal' 카테고리의 다른 글
How to make trippleA level interactive Snow in Unreal Engine (Deformable Snow) (0) | 2024.09.09 |
---|---|
[번역]Graphics programming 개요 (0) | 2018.02.22 |
UE4 Lightmass 및 GI (0) | 2016.01.13 |
UE4 Viewport Setting (0) | 2015.12.14 |
UDK3 다채널 UV 제어 (0) | 2014.05.26 |