2024. 6. 26. 18:43ㆍUnreal Engine
이번 글은 ue 와 블루프린트 편집가와 잘 통합되는 c++ 클래스와 구조체의 생성 방법을 설명하는데 초점을 둔다.
UObject에서 파생된 UCLASS는 U 로 시작하는 이름이어야 한다.
Actor에서 파생된 UCLASS는 A로 시작하는 이름이어야 한다.
UObject에서 직접 파생된 오브젝트는 UStaticMeshs와 같은 시각적 표현 요소가 포함되어있어도 레벨에 배치 할 수 없다.
오브젝트를 레벨에 배치하고싶다면 Actor 클래스에서 파생되거나 그 상속 아래 계층에 있어야 한다.
UE는 UCLASS를 위한 많은 양의 코드를 생성하고 관리한다.
이 코드는 UPROPERTY, UFUNCTION, UCLASS 매크로와 같은 UE 매크로를 사용한 결과로 생선된다
생성된 코드는 UserProfile.generated.h에 저장된다 성공적으로 컴파일 하려면 UserProfile.generated.h 파일과
UserProfile.h 파일을 #include 해야만 한다.
1
2
3
4
5
6
7
|
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "UserProfile.h"
#include "Chapter_02GameModeBase.generated.h"
|
cs |
UserProfile.generated.h 파일은 가장 마지막에 #include 되어야 하며 그렇지 아니하면 오류가 발생한다.
다음과 같이 UCLASS의 동작에 변화를 주는 다수의 키워드가 존재한다.
키워드 | 설명 |
Blueprintable | UE 편집기 내의 Class Viewer에서 블루프린트를 생성하고자 할 때 사용한다. 이 키워드를 사용하지 않으면 UCLASS에 대해 Create Blueprint Class 옵션을 사용 할 수 없다. |
NotBlueprintType | 이 키워드를 사용하면 이 블루프린트 변수 타입을 블루프린트 다이어그램에서 변수로 사용할 수 없게 된다. ClassViewer에서 UCLASS 이름을 마우스 오른쪽 버튼으로 클릭해도 컨텍스트 메뉴에 Create Blueprint Class 메뉴가 나타나지 않는다. |
BlueprintType | 이 키워드를 사용하면 UCLASS를 사른 블루프린트에서 변수처럼 사용 할 수 있다, |
UCLASS( BlueprintType)
class CHAPTER_02_API AChapter_02GameModeBase : public AGameModeBase
{
GENERATED_BODY()
public:
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category = UClassNames )
TSubclassOf<UUserProfile> UPBlueprintClassName;
void BeginPlay();
};
다음과 같이 사용된다.
사용자 편집이 가능한 UPROPERTY 생성
선언된 각 UCLASS가 선언 할 수 있는 UPROPERTY 수에는 제한이 없다.
각 UPROPERTY는 시각적 편집이 가능하거나 블루프린트로 접근 가능한 UCLASS의 데이터 멤버이다.
General
이 항목은 일반적인, 대부분의 경우에서 작성되는 평범함 변수에 대해서 붙는 지정자들에 대해 알아보겠습니다. 요약하자면, 가장 많이 쓰이는 지정자라고 할 수 있겠습니다.
프로퍼티 지정자 | 설명 |
BlueprintReadWrite | 이 프로퍼티는 블루프린트에서 읽거나 쓸 수 있습니다. BlueprintReadOnly 지정자와 호환되지 않습니다. |
위 지정자를 사용하면 블루프린트 에디터 내 내 블루프린트 패널 또는 우클릭 액션 목록에서 'Get/Set 변수명'을 이벤트 그래프 또는 함수 창에서 사용할 수 있음을 의미합니다. | |
BlueprintReadOnly | 이 프로퍼티는 블루프린트에서 읽을 수는 있지만 변경은 안됩니다. BlueprintReadWrite 지정자와 호환되지 않습니다. |
위 지정자를 사용하면 블루프린트 에디터 내 내 블루프린트 패널 또는 우클릭 액션 목록에서 'Get 변수명'을 이벤트 그래프 또는 함수 창에서 사용할 수 있음을 의미합니다. | |
BlueprintSetter =SetterFunctionName | 이 프로퍼티에는 커스텀 뮤테이터(Mutator, Setter 다른 말) 함수가 있으며, 묵시적으로 BlueprintReadWrite 지정자가 붙습니다. 참고로 뮤터이터 함수는 같은 클래스 이름으로 그 일부를 따서 지어야 합니다. |
BlueprintReadWrite를 바탕으로 블루프린트에서 변수를 Set할 때 SetterFunctionName 함수를 Setter 함수로 실행시킨다는 것을 의미합니다. | |
BlueprintGetter =GetterFunctionName | 이 프로퍼티에는 커스텀 액세서(Accessor, Getter의 다른말) 함수를 지정합니다. 또한 BlueprintSetter 또는 BlueprintReadWrite 지정자가 지정되지 않으면, BlueprintReadOnly로 간주합니다. |
블루프린트에서 변수를 Get할 때 GetterFunctionName 함수를 Getter 함수로 실행시킨다는 것을 의미합니다. | |
EditAnywhere | 이 프로퍼티는 아키타입이나 인스턴스 양쪽의 프로퍼티 창에서 편집할 수 있습니다. 이 지정자는 어떤 "Visible" 지정자와도 호환되지 않습니다. |
레벨에 배치된 클래스를 클릭했을 때 나오는 디테일 창 및 블루프린트 에디터의 디테일 창에서 해당 변수가 노출되며, 편집가능한 상태가 됩니다. | |
VisibleAnywhere | 이 프로퍼티는 모든 프로퍼티 창에서 보이지만 편집할 수 없음을 나타냅니다. 이 지정자는 어떤 "Edit" 지정자와도 호환되지 않습니다. |
레벨에 배치된 클래스를 클릭했을 때 나오는 디테일 창 및 블루프린트 에디터의 디테일 창에서 해당 변수가 노출되지만, InputField가 회색으로 블록되어 편집할 수 없습니다. | |
EditDefaultsOnly | 이 프로퍼티는 프로퍼티 창에서 편집할 수 있지만, 아키타입 상에서만 가능합니다. 이 지정자는 어떤 "Visible" 지정자와도 호환되지 않습니다. |
블루프린트 에디터의 디테일 창에서만 해당 변수가 노출되며, 편집가능한 상태가 됩니다. | |
VisibleDefaultsOnly | 이 프로퍼티는 아키타입에 대한 프로퍼티 창에서 보이기만 할 뿐, 편집할 수는 없음을 나타냅니다. 이 지정자는 어떤 "Edit" 지정자와도 호환되지 않습니다. |
블루프린트 에디터의 디테일 창에서만 해당 변수가 노출되며, InputField가 회색으로 블록되어 편집할 수 없습니다. | |
EditInstanceOnly |
이 프로퍼티는 프로퍼티 창에서 편집할 수 있지만, 아키타입이 아닌 인스턴스 상에서만 가능합니다. 이 지정자는 어떤 "Visible" 지정자와도 호환되지 않습니다. |
레벨 에디터에 배치된 인스턴스의 디테일 창에서만 해당 변수가 노출되며, 편집가능한 상태가 됩니다. | |
VisibleInstanceOnly |
이 프로퍼티는 아키타입이 아닌 인스턴스에 대한 프로퍼티 창에서 보이기만 할 뿐, 편집할 수는 없음을 나타냅니다. 이 지정자는 어떤 "Edit" 지정자와도 호환되지 않습니다. |
레벨 에디터에 배치된 인스턴스의 디테일 창에서만 해당 변수가 노출되며, InputField가 회색으로 블록되어 편집할 수 없습니다. | |
Category=" TopCategory| SubCategory|..." | 블루프린트 편집 툴에 이 프로퍼티를 표시할 때의 카테고리르 지정합니다. 중첩 카테고리는 | 연산자로 정의합니다. |
블루프린트의 내 블루프린트 패널, 우클릭 액션 목록, 디테일 창 등 표시될 수 있는 곳에 카테고리가 매겨집니다. | |
메타데이터 지정자 | 설명 |
AllowPrivateAccess =true | 정의되지 않음 |
C++ 코드상에서 private 접근 한정자로 수식된 변수에 대해 접근을 허용하여, 블루프린트 상에 노출시킬 수 있도록 돕습니다. |
UObject 파생 클래스 인스턴스화 (ConstructObject<>와 NewObject<>)
c++ 클래스가 아닌 UE 블루프린트 클래스의 인스턴스를 생성해야하는 상황에서 UObject에서 파생된 클래스를 만들때는 특별한 UE 엔진 함수를 사용해야 한다.
팩토리 메서드는 UE가 오브젝트에 대한 어느정도의 메모리 관리를 수행해 오브젝트가 삭제될 때 해당 오브젝트에 대한 모든 참조가 쉽게 연결 해제될 수 있도록 한다. 이로써 무효화된 메모리에 대한 참조가 있는 임의의 포인터가 사라지도록 돕는데 이런 과정을 보통 가비지 컬렉션이라고 부른다.
AActor 클래스의 파생이 아닌 UObject에서 파생된 클래스를 인스턴스화 할 때는 UWorld::SpawnActor<>를 사용하는 대신 특별한 글로벌 함수인 ConstructObject<> 또는 NewObject<> 를 사용한다. UE object 클래스에서 파생된 새 인스턴스를 사용하기 위해 C++ 키워드인 new를 사용해서는 안된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#include "Chapter_02GameModeBase.h"
void AChapter_02GameModeBase::BeginPlay()
{
AChapter_02GameModeBase * gm = Cast<AChapter_02GameModeBase>( GetWorld()->GetAuthGameMode() );
if( gm )
{
// Create object
UUserProfile* newobject = NewObject<UUserProfile>( (UObject*)GetTransientPackage(),
UUserProfile::StaticClass() );
// Destroy object
if(newobject)
{
newobject->ConditionalBeginDestroy();
newobject = nullptr;
}
}
}
|
cs |
NewObject를 사용해 UObject 클래스를 생성하는 과정은 간단하다. ConstructObject를 사용하면 블루프린트 클래스 타입의 오브젝트를 인스턴스화하고 C++포인터를 반환한다
UObject 파생 오브젝트를 만들 때는 new 키워드를 사용하면 안 된다 new키워드를 사용하면 메모리 관리가 제대로 되지 않는다.
NewObject 함수는 객체지향 프로그래밍 세계에서 Factory Patten이다 오브젝트를 생성할 때 직접 생성하는 대신 팩토리에 원하는 오브젝트의 생성을 요청하는 방식이다.
ConditionalBeginDestroy() 함수는 내부 엔진 연결을 모드 제거하는 방식으로 프로세스를 시작한다
내부 속성을 먼저 파괴한 후 실제 오브젝트를 파괴하는 과정으로 전체적인 프로세스를 진행한다.
오브젝트의 ConditionalBeginDestroy()가 호출된 이후부터 클라이언트 코드는 오브젝트가 파괴된 것으로
간주하고 더이상 하용하지 않아야 한다. 실제 메모리 복구는 ConditionalBeginDestroy()가 호출되면
잠시 후 진행된다 일정한 주기로 게임 프로그램에서 더 이상 참조하지 않는 오브젝트의 메모리 삭제를 진행하는 가비지 컬렉션 루틴이 존재한다.
'Unreal Engine' 카테고리의 다른 글
UE5 PossessedBy() 와 OnRep_ 함수 (0) | 2024.07.25 |
---|---|
UnrealEngine EnhancedInput (0) | 2024.07.25 |
Garbage Collection(가비지 컬렉션) (0) | 2024.06.28 |
커스텀 엑터 생성하기 (0) | 2024.06.26 |
메모리 관리, 스마트 포인터, 디버깅 (0) | 2024.06.26 |