일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- virtual function
- implicit conversion
- 영화
- lua
- 메타테이블
- 영화 리뷰
- 상속
- more effective c++
- 다형성
- c++
- UE4
- 티스토리챌린지
- reference
- Smart Pointer
- 암시적 변환
- effective stl
- 오블완
- 비교 함수 객체
- resource management class
- 언리얼
- 반복자
- 참조자
- exception
- 루아
- Vector
- 예외
- operator new
- 게임
- 스마트 포인터
- Effective c++
- Today
- Total
스토리텔링 개발자
[UE4] 오브젝트 생성(Create Object) 본문
개요
언리얼은 오브젝트 생성에 대한 다양한 방법을 제공합니다.
어떤 상황에서 어떤 메소드를 사용하는 것이 좋을까요?
오브젝트 생성
오브젝트를 생성하는 대표적인 메소드들입니다.
ActorSpawn / NewObject
생성자에서는 사용할 수 없습니다.
일반적으로 BeginPlay에서 사용합니다.
CreateDefaultSubobject
생성자에서만 사용 가능합니다.
생성자의 매개변수인 FObjectInitializer를 전달해야 하기 때문입니다.
즉, 해당 함수로 오브젝트를 생성하려면 사용할 수 있는 FObjectInitializer가 있어야 합니다.
오브젝트는 서브 오브젝트(혹은 컴포넌트)로 생성됩니다.
각각은 생성자에서 사용하느냐, 아니냐로 구분됩니다.
NewObject의 매개변수
NewObject 메소드는 다양한 오버로드를 가지고 있습니다.
오버로드의 각 매개변수에 대해 정리해 보았습니다.
UObject* Outer
생성하는 오브젝트를 소유할 오브젝트를 설정합니다.
(SceneComponent의 자식으로 붙이는 것과는 다른 의미입니다.)
const UClass* Class
생성할 오브젝트의 UClass(리플렉션을 위한 클래스 타입에 대한 정보)입니다.
StaticClass()를 사용해서 전달할 수 있습니다.
Class를 매개변수로 받지 않는 버전도 존재합니다.
NewObject의 템플릿 버전에서는 내부적으로 StaticClass 함수를 호출하기 때문입니다.
FName Name
생성할 오브젝트의 이름입니다.
EObjectFlags Flags
생성할 오브젝트에 설정할 플래그 값입니다.
오브젝트에 각종 처리를 가할 때 사용합니다.
(아래 링크의 '오브젝트 플래그' 를 참조)
UObject* Template
Template에 설정된 값을 새로 생성하는 오브젝트에도 동일하게 적용해 줍니다.
즉, Template의 카피본을 만듭니다.
생성자의 FObjectInitializer
FObjectInitializer는 UObject의 생성자가 취하는 매개변수입니다.
이 매개변수를 통해 CDO(Class Default Object)가 어떤 서브 오브젝트(혹은 컴포넌트)를 포함할지 등을 조작할 수 있습니다.
해당 객체의 대표적인 함수로는 CreateDefaultSubobject(), DoNotCreateDefaultSubobject() 가 있습니다.
생성자 시점에서 Subobject 혹은 Component를 생성할지 말지의 여부를 조작합니다.
FObjectInitializer::CreateDefaultSubobject는 생성자에서 UObject를 생성할 때 사용하는 함수 이름과 동일하다는 점은 눈여겨 볼 만 합니다.
용법은 아래와 같습니다.
AUDKEmitterPool::AUDKEmitterPool(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.DoNotCreateDefaultSubobject(TEXT("SomeComponent")).DoNotCreateDefaultSubobject(TEXT("SomeOtherComponent")))
{
// 여기서 CDO 프로퍼티를 초기화시킵니다.
}
여기서 유념해서 봐야 할 부분은 FObjectInitializer가 const로 넘어온다는 점입니다.
(위 예제에서도 (const FObjectInitializer& ObjectInitializer) 의 형태로 넘어오는 것을 확인할 수 있습니다.)
각 생성자에서 조작, 변경되어야 할 FObjectInitializer가 상수로 넘어온다는 건 좀 의아합니다.
상수 객체에 어떻게 그것이 가능할까요?
방법은 간단합니다.
ObjectInitializer는 조작을 위한 함수들을 호출할 경우, 새로운 FObjectInitializer를 리턴합니다.
즉, 조작이 필요한 경우 새로운 객체를 생성하여 전달하므로 상수여도 문제가 없습니다.
UObject Body 매크로
UObject는 매크로로 각종 기본 함수들을 생성합니다.
그리고 그 기본 함수들 속에는 생성자도 포함되어 있습니다.
이 시점에서 매크로를 다루는 이유입니다.
생성자에서 오브젝트를 생성하고 싶다면 생성자를 정의하는 부분부터 살펴봐야겠지요.
매크로는 생성자에 따라 두 가지 버전이 있습니다.
GENERATED_BODY()
일반적으로 사용하는 매크로입니다.
이 버전은 생성자를 직접 헤더에 선언 / cpp 파일에 정의해 주어야 합니다.
헤더 파일
UCLASS()
class TEST_API UTestObject : public UObject
{
GENERATED_BODY()
public:
// 명시적인 선언이 필요함.
UTestObject(const FObjectInitializer& ObjectInitializer);
}
USTRUCT()
class TEST_API FTestObject
{
GENERATED_BODY()
public:
// 명시적인 선언이 필요함.
// UObject가 아니므로 이니셜라이저 매개변수가 없음.
FTestObject();
}
cpp 파일
UTestObject::UTestObject(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) { }
FTestObject::FTestObject() { }
GENERATED_UCLASS_BODY()
헤더에 생성자를 선언할 필요가 없습니다.
cpp에 정의만 해주면 됩니다.
헤더 파일
UCLASS()
class TEST_API UTestObject : public UObject
{
GENERATED_UCLASS_BODY()
// 생성자 선언 불필요
}
USTRUCT()
class TEST_API FTestObject
{
GENERATED_USTRUCT_BODY()
// 생성자 선언 불필요
}
cpp 파일
// 하지만 정의는 해야 함
UTestObject::UTestObject(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) { }
FTestObject::FTestObject() { }
'개발 > 언리얼 엔진' 카테고리의 다른 글
[UE4] 텍스쳐 스트리밍 시스템(Mipmap) (0) | 2021.09.29 |
---|---|
[UE4] 컬링(Culling) (0) | 2021.09.17 |
[UE4] 언리얼 프로퍼티(리플렉션) 시스템(Unreal Property System) (0) | 2021.08.24 |
[UE4] 프로퍼티(UPROPERTY) (0) | 2021.08.18 |
[UE4] 스마트 포인터(Smart Pointer) (0) | 2021.08.09 |