[ UE5 공식 문서 학습 ]
[ Object - The UCLASS Macro]
: https://dev.epicgames.com/documentation/ko-kr/unreal-engine/objects-in-unreal-engine
The UCLASS macro gives the UObject a reference to a UCLASS that describes its Unreal based type. Each UCLASS maintains one Object called the Class Default Object(CDO). The CDO is essentially a default 'template' Object, generated by the class constructor and unmodified thereafter.
Both the UCLASS and the CDO can be retrieved for a given Object instance, although they should generally be considered read-only. The UCLASS for an Object instance can be accessed at any time using the GetClass() function.
A UCLASS contains a set of properties and functions that define the class. These are normal C++ functions and variables available to standard C++ code, but tagged with Unreal Engine specific metadata that controls how they behave within the Object system. For more details about the tagging syntax, refer to the Programming Reference.
UCLASS 매크로는 UObject에 Unreal 기반 유형을 설명하는 UCLASS에 대한 참조를 제공합니다. 각 UCLASS는 Class Default Object(CDO)라는 하나의 Object를 유지합니다. CDO는 본질적으로 클래스 생성자에 의해 생성되고 그 후 수정되지 않는 기본 '템플릿' Object입니다.
UCLASS와 CDO는 모두 주어진 Object 인스턴스에 대해 검색할 수 있지만 일반적으로 읽기 전용으로 간주해야 합니다. Object 인스턴스의 UCLASS는 GetClass() 함수를 사용하여 언제든지 액세스할 수 있습니다.
UCLASS에는 클래스를 정의하는 속성과 함수 세트가 포함되어 있습니다. 이들은 표준 C++ 코드에서 사용할 수 있는 일반적인 C++ 함수와 변수이지만 Object 시스템 내에서 동작하는 방식을 제어하는 Unreal Engine 특정 메타데이터로 태그가 지정됩니다. 태그 구문에 대한 자세한 내용은 Programming Reference를 참조하세요.
==== ==== ==== ==== ==== ====
: 생성자에 의해서 CDO를 생성해두고, 생성자를 수정해서 컴파일할 경우 CDO도 변경된다.
[ Unreal Object Handling ]
: https://dev.epicgames.com/documentation/ko-kr/unreal-engine/unreal-object-handling-in-unreal-engine
[ Automatic Updating of References (언리얼 오브젝트 처리 - 레퍼런스 자동 업데이트) ]
When an AActor or UActorComponent is destroyed or otherwise removed from play, all references to it that are visible to the reflection system (UProperty pointers and pointers stored in Unreal Engine container classes such as TArray) are automatically nulled. This is beneficial in that it prevents dangling pointers from persisting and causing trouble down the road, but it also means that AActor and UActorComponent pointers can become null if some other piece of code destroys them. The ultimate advantage of this is that null-checking is more reliable, as it detects both standard case null pointers and cases where a non-null pointer would have been pointing at deleted memory.
It is important to realize that this feature applies only to UActorComponent or AActor references marked with UPROPERTY or stored in an Unreal Engine container class. An Object reference stored in a raw pointer will be unknown to the Unreal Engine, and will not be automatically nulled, nor will it prevent garbage collection. Note this does not mean that all UObject* variables must be UProperties. If you want an Object pointer that is not a UProperty, consider using TWeakObjectPtr. This is a "weak" pointer, meaning it will not prevent garbage collection, but it can be queried for validity before being accessed and will be set to null if the Object it points to is destroyed.
Another case where a referenced UObject UProperty will be automatically null'ed is when using 'Force Delete' on an asset in the editor. As a result, all code operating on UObjects which are assets must handle these pointers becoming null.
AActor 또는 UActorComponent가 파괴되거나 다른 방식으로 플레이에서 제거되면 리플렉션 시스템에서 볼 수 있는 모든 참조(UProperty 포인터 및 TArray와 같은 Unreal Engine 컨테이너 클래스에 저장된 포인터)가 자동으로 null이 됩니다. 이는 댕글링 포인터가 지속되어 나중에 문제를 일으키는 것을 방지한다는 점에서 유익하지만, 다른 코드 조각이 이를 파괴하면 AActor 및 UActorComponent 포인터가 null이 될 수 있다는 의미이기도 합니다. 이것의 궁극적인 장점은 null 검사가 더 안정적이라는 것입니다. 일반적인 null 포인터와 null이 아닌 포인터가 삭제된 메모리를 가리키는 경우를 모두 감지하기 때문입니다.
이 기능은 UPROPERTY로 표시되어있거나 Unreal Engine 컨테이너 클래스에 저장된 UActorComponent 또는 AActor 레퍼런스에만 적용된다는 것을 아는 것이 중요합니다. raw 포인터에 저장된 Object 레퍼런스는 Unreal Engine에서 알 수 없으며 자동으로 null이 되지 않으며 가비지 컬렉션을 방지하지도 않습니다. 이는 모든 UObject* 변수가 UProperty여야 한다는 것을 의미하지 않습니다. UProperty가 아닌 Object 포인터가 필요한 경우 TWeakObjectPtr을 사용하는 것을 고려하세요. 이는 "약한" 포인터로, 가비지 컬렉션를 방지하지는 않지만 액세스하기 전에 유효성을 확인할 수 있으며 가리키는 Object가 파괴되면 null로 설정됩니다.
참조된 UObject UProperty가 자동으로 null이 되는 또 다른 경우는 편집기에서 에셋에다가 '강제 삭제'를 사용할 때입니다. 결과적으로 에셋인 UObject에서 작동하는 모든 코드는 이러한 포인터가 null이 되는 것을 처리해야 합니다.
==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
: 댕글링 포인터를 방지하기 위해 UPROPERTY로 표시하거나 언리얼 컨테이너에 저장되어있는 UObject 계열 포인터들은 파괴되어 더 이상 참조되지 않으면 nullptr로 변경된다. 하지만 이렇게 UPROPERTY로 참조하는 것은 GC와도 연관되어 있는데, 이를 위해 TweakObjectPtr을 제공하여 GC 레퍼런스 카운트에 영향을 미치지않고 댕글링 포인터를 방지할 수 있도록 제공한다.
[ Run-Time Type Information and Casting (런타임 유형 정보 및 형변환) ]
Because UObjects are part of the Unreal Engine's reflection system, they always know what UClass they are, and type-related decisions and casts can be made at runtime.
In native code, every UObject class has a custom Super typedef set to its parent class, which allows easy control of overriding behavior. As an example:
Also, you can safely cast an Object from a base class to a more derived class using the templated Cast function, or query if an Object is of a particular class using IsA. A quick example follows:
Here we have used Cast to attempt to cast the AEnemy to an AMegaBoss. If the Object in question is not actually an AMegaBoss (or a child class thereof), the cast will return a null pointer and we can react appropriately. In the code above, the Incinerate function will only be called against the MegaBoss.
UObject는 언리얼 엔진의 리플렉션 시스템의 일부이므로 항상 자신이 어떤 UClass인지 알고 있으며, 런타임에 타입 관련 결정과 캐스팅을 할 수 있습니다.
네이티브 코드에서, 모든 UObject 클래스는 부모 클래스로 설정된 사용자 지정 Super typedef를 가지므로 오버라이딩 동작을 쉽게 제어할 수 있습니다. (ex : Super::Speak() in virtual override function)
또한 템플릿 Cast 함수를 사용하여 기본 클래스에서 더 파생된 클래스로 Object를 안전하게 캐스트하거나 IsA를 사용하여 Object가 특정 클래스인지 확인할 수 있습니다. 간단한 예는 다음과 같습니다.
여기서 Cast를 사용하여 AEnemy를 AMegaBoss로 캐스트하려고 했습니다. 문제의 Object가 실제로 AMegaBoss(또는 그 자식 클래스)가 아닌 경우 캐스트는 nullptr을 반환하고 적절하게 대응할 수 있습니다. 위의 코드에서 Incinerate 함수는 MegaBoss에 대해서만 호출됩니다.
==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
: 오버라이딩이 잦은 언리얼엔진 게임 프로그래밍 특성상 Super:: 를 통해 부모 함수의 코드를 쉽게 가져올 수 있다.
리플렉션 시스템을 통해 런타임에 O(1)의 비용으로 타입에 관한 정보를 얻거나 업캐스팅, 다운캐스팅을 안전하게 할 수 있다. 실패할 경우 nullptr을 리턴한다. 에디터의 경우 O(상속레벨)의 비용.
[ Garbage Collection ]
Unreal implements a garbage collection scheme whereby UObjects that are no longer referenced or have been explicitly flagged for destruction will be cleaned up at regular intervals. The engine builds a reference graph to determine which UObjects are still in use and which ones are orphaned. At the root of this graph is a set of UObjects designated as the "root set". Any UObject can be added to the root set. When garbage collection occurs, the engine can track all referenced UObjects by searching the tree of known UObject references, starting from the root set. Any unreferenced UObjects, meaning those which are not found in the tree search, will be assumed to be unneeded, and will be removed.
Unreal은 가비지 컬렉션 스키마를 구현하여 더이상 참조되지 않거나 명시적으로 파괴 플래그가 지정된 UObject 를 일정한 간격으로 정리합니다. 엔진은 레퍼런스 그래프를 만들어 어떤 UObject 가 아직 사용중이고 어떤 것이 고아가 되었는지 확인합니다. 이 그래프의 루트에는 "Root Set"으로 지정된 a set of UObjects가 있습니다. 어떤 UObject 도 Root Set에 추가할 수 있습니다. 가비지 컬렉션이 발생하면, 엔진은 Root Set부터 시작해 알려진 UObject 레퍼런스 트리를 탐색하여 참조된 모든 UObject 를 추적할 수 있습니다. 참조되지 않은 UObject , 즉 트리 탐색에서 찾을 수 없는 것은 불필요한 것으로 간주하여 제거됩니다.
One practical implication here is that you typically need to maintain a UPROPERTY reference to any Object you wish to keep alive, whether it's a simple Object pointer or an Unreal Engine container class that contains Object pointer types, such as TArray<UObject*>. Actors and their Components are frequently an exception to this, since the Actors are usually referenced by an Object that links back to the root set, such as the Level to which they belong, and the Actor's Components are referenced by the Actor itself. Actors can be explicitly marked for destruction by calling their Destroy function, which is the standard way to remove an Actor from an in progress game. Components can be destroyed explicitly with the DestroyComponent function, but they are usually destroyed when their owning Actor is removed from the game.
여기서 한 가지 실질적으로 시사하는 바는, 단순 오브젝트 포인터 또는 TArray<UObject*> 같은 오브젝트 포인터 유형이 포함된 언리얼 엔진 컨테이너 클래스든, 살려두고자 하는 오브젝트에 대한 UPROPERTY 레퍼런스를 유지해야 한다는 것입니다. 액터와 그 컴포넌트는 종종 예외인데, 액터는 보통 자신이 속해있는 레벨(맵)처럼, Root Set로 다시 연결되는 오브젝트에 의해 참조되고, 액터의 컴포넌트는 액터 자체에 의해 참조되기 때문입니다. 액터는 Destroy 함수를 호출하여 명시적으로 소멸을 마킹할 수 있는데, 이는 진행 중인 게임에서 액터를 제거하는 표준 방법입니다. 컴포넌트는 DestroyComponent 함수로 명시적으로 소멸시킬 수 있지만, 보통은 소유 액터가 게임에서 제거되면 소멸됩니다.
Garbage collection in Unreal Engine 4 is fast and efficient, and has a number of built-in features designed to minimize overhead, such as multithreaded reachability analysis to identify orphaned Objects, and unhashing code optimized to remove Actors from containers as quickly as possible. There are other features that can be adjusted to gain more precise control over how and when garbage collection is performed, most of which are found in Project Settings under Engine - Garbage Collection. The following settings are commonly used to tune garbage collector performance for a project:
언리얼 엔진 4 의 가비지 컬렉션은 빠르고 효율적이며, 고아 오브젝트를 식별하기 위한 멀티스레드 reachability 분석, 컨테이너에서 액터를 최대한 빨리 제거하도록 최적화된 언해싱 코드 등 오버헤드를 최소화하도록 설계된 여러 내장 기능이 있습니다. 가비지 콜렉션을 수행하는 방법과 시기를 보다 정확하게 제어하기 위해 조정할 수 있는 다른 기능이 있으며, 대부분은 엔진 - 가비지 콜렉션의 프로젝트 세팅에서 찾을 수 있습니다. 다음 설정은 프로젝트의 가비지 수집기 성능을 조정하는 데 일반적으로 사용됩니다.
==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
: 모든 UObject들은 명시적으로 파괴되었거나 더 이상 참조되지 않는 경우 GC에 의해 자동으로 메모리 해제된다. 레퍼런스 그래프를 만들어 Root Set부터 트리 탐색을 시작하는데, 어떤 UObject들이 사용 중이고 어떤 것들이 Root Set으로 부터 탐색되지 않아 떨어졌는지(고아가 되었는지) 확인하여 그런 것들은 Unreachable 로 판단하여 해당 메모리를 해제한다.
GC에 수거되지 않게 하기 위한 모든 UObject 들은 UPROPERTY() 매크로를 통해 참조를 유지해야 한다. 액터와 액터컴포넌트 단위가 GC되지 않는 이유는 레벨에 배치되면 Root Set에 존재하는 레벨에 의해 다시 참조되기 때문이다.
UObject들은 AddToRoot() 함수를 통해 GUObjectArray에 있는 RootSet Flag를 추가함으로써 GC에 의해 수집되지 않도록 프로그래머가 명시적으로 지정해줄 수 있다.
[ UObject를 통해 제공되는 함수 기능 ]
가비지 컬렉션
레퍼런스 업데이트
리플렉션
직렬화
디폴트 프로퍼티 변경사항의 자동 업데이트
자동 프로퍼티 초기화
자동 에디터 통합
런타임에 사용 가능한 타입 정보
네트워크 리플리케이션
[ 언리얼 헤더 툴 (UHT) ]
UObject 파생 타입이 제공하는 기능을 활용하려면 해당 타입에 대한 헤더 파일에 전처리 단계를 실행하여 필요한 정보를 대조해야 합니다. 이 전처리 단계는 UnrealHeaderTool, 줄여서 UHT에서 수행합니다. UObject 파생 타입에는 준수해야 하는 특정 구조가 있습니다.
#pragma once
#include 'Object.h'
#include 'MyObject.generated.h'
UCLASS()
class MYPROJECT_API UMyObject : public UObject
{
GENERATED_BODY()
};
generated.h, UCLASS(), GENERATED_BODY(), MYPROJECT_API
'UE5' 카테고리의 다른 글
[UE5] TWeakObjectPtr (4) | 2024.11.06 |
---|---|
[UE5] CreateDefaultSubobject, NewObject, SpawnActor (0) | 2024.11.03 |
[UE5] LineTrace Cost (3) | 2024.10.18 |
[UE5] Widget Blueprint가 추가된 후 보이지 않음 (0) | 2024.07.29 |
[UE5] UE_LOG, FName (0) | 2024.07.25 |