[UE] 언리얼 리플렉션 Unreal Reflection II

언리얼 오브젝트 리플렉션 시스템의 활용하여 언리얼 오브젝트 리플렉션 시스템을 사용해 언리얼 오브젝트를 다루는 방법의 학습하자.
인프런 이득우님의 '언리얼 프로그래밍 Part1 - 언리얼 C++의 이해' 강의를 참고하였습니다.
😎 [이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해] 강의 들으러 가기!
목차
언리얼 리플렉션 Unreal Reflection II
예제 클래스 다이어그램
- 어떤 학교에서 학생과 교수가 함께 수업하는 상황을 구현하고 싶다.
- 학교 정보는 GameInstance에서 지정
- 인물 클래스 Person
- 학생 클래스 Student
- 선생 클래스 Teacher

예제 코드
Person.h
더보기
#pragma once #include "CoreMinimal.h" #include "UObject/NoExportTypes.h" #include "Person.generated.h" UCLASS() class PRACTICEUNREAL_API UPerson : public UObject { GENERATED_BODY() public: UPerson(); // 생성자 UFUNCTION() virtual void DoLesson(); // 가상 함수 const FString& GetName() const; void SetName(const FString& InName); protected: UPROPERTY() FString Name; UPROPERTY() int32 Year; };
Person.cpp
더보기
#include "Person.h" UPerson::UPerson() { Name = TEXT("홍길동"); Year = 1; } void UPerson::DoLesson(){ UE_LOG(LogTemp, Log, TEXT("%s님이 수업에 참여합니다."), *Name); } const FString& UPerson::GetName() const{ return Name; } void UPerson::SetName(const FString& InName){ Name = InName; }
Student.h
더보기
#pragma once #include "CoreMinimal.h" #include "UObject/NoExportTypes.h" #include "Person.h" #include "Student.generated.h" UCLASS() class OBJECTREFLECTION_API UStudent : public UPerson { GENERATED_BODY() public: UStudent(); virtual void DoLesson() override; private: UPROPERTY() int32 Id; };
Student.cpp
더보기
#include "Student.h" UStudent::UStudent() { Name = TEXT("이학생"); Year = 1; Id = 1; } void UStudent::DoLesson() { Super::DoLesson(); UE_LOG(LogTemp, Log, TEXT("%d학년 %d번 %s님이 수업을 듣습니다."), Year, Id, *Name); }
Teacher.h
더보기
#pragma once #include "CoreMinimal.h" #include "UObject/NoExportTypes.h" #include "Person.h" #include "Teacher.generated.h" UCLASS() class OBJECTREFLECTION_API UTeacher : public UPerson { GENERATED_BODY() public: UTeacher(); virtual void DoLesson() override; private: UPROPERTY() int32 Id; };
Teacher.cpp
더보기
#include "Teacher.h" UTeacher::UTeacher() { Name = TEXT("이선생"); Year = 3; Id = 1; } void UTeacher::DoLesson() { Super::DoLesson(); UE_LOG(LogTemp, Log, TEXT("%d년차 선생님 %s님이 수업을 강의합니다."), Year, *Name); }
MyGameInstance.h
더보기
#pragma once #include "CoreMinimal.h" #include "Engine/GameInstance.h" #include "MyGameInstance.generated.h" UCLASS() class OBJECTREFLECTION_API UMyGameInstance : public UGameInstance { GENERATED_BODY() public: UMyGameInstance(); virtual void Init() override; private: UPROPERTY() FString SchoolName; };
MyGameInstance.cpp
더보기
#include "MyGameInstance.h" // 해당 언리얼 오브젝트에 선언된 헤더가 가장 위에 위치해야 한다. #include "Student.h" #include "Teacher.h" #include 순서도 중요하다. 아래와 같이 다른 언리얼 오브젝트 헤더가 더 위에 위치한 경우 헤더툴이 에러를 띄운다. #include "Student.h" #include "Teacher.h" #include "MyGameInstance.h" UMyGameInstance::UMyGameInstance() { SchoolName = TEXT("기본학교"); } void UMyGameInstance::Init() { Super::Init(); UE_LOG(LogTemp, Log, TEXT("=============================")); UClass* ClassRuntime = GetClass(); UClass* ClassCompile = UMyGameInstance::StaticClass(); UE_LOG(LogTemp, Log, TEXT("학교를 담당하는 클래스 이름 : %s"), *ClassRuntime->GetName()); SchoolName = TEXT("청강문화산업대학교"); UE_LOG(LogTemp, Log, TEXT("학교 이름 : %s"), *SchoolName); UE_LOG(LogTemp, Log, TEXT("학교 이름 기본값 : %s"), *GetClass()->GetDefaultObject<UMyGameInstance>()->SchoolName); UE_LOG(LogTemp, Log, TEXT("=============================")); UStudent* Student = NewObject<UStudent>(); UTeacher* Teacher = NewObject<UTeacher>(); Student->SetName(TEXT("학생1")); UE_LOG(LogTemp, Log, TEXT("새로운 학생 이름 %s"), *Student->GetName()); FString CurrentTeacherName; FString NewTeacherName(TEXT("이득우")); FProperty* NameProp = UTeacher::StaticClass()->FindPropertyByName(TEXT("Name")); if (NameProp) { NameProp->GetValue_InContainer(Teacher, &CurrentTeacherName); UE_LOG(LogTemp, Log, TEXT("현재 선생님 이름 %s"), *CurrentTeacherName); NameProp->SetValue_InContainer(Teacher, &NewTeacherName); UE_LOG(LogTemp, Log, TEXT("새로운 선생님 이름 %s"), *Teacher->GetName()); } UE_LOG(LogTemp, Log, TEXT("=============================")); Student->DoLesson(); UFunction* DoLessonFunc = Teacher->GetClass()->FindFunctionByName(TEXT("DoLesson")); if (DoLessonFunc) { Teacher->ProcessEvent(DoLessonFunc, nullptr); } UE_LOG(LogTemp, Log, TEXT("=============================")); }
실행화면

리플렉션 시스템 (위의 예제 코드 분석)
NewObject<클래스 이름>()
C++에서의 new 키워드가 언리얼 UObject에서는 NewObject<클래스 이름>() 과 유사하다.
UStudent* Student = NewObject<UStudent>(); UTeacher* Teacher = NewObject<UTeacher>();
리플렉션을 통한 프로퍼티 변경
Get, Set 함수를 사용하는 방법이 아닌, 언리얼 엔진에서 제공하는 리플렉션 시스템을 사용해서 변경
FString CurrentTeacherName; FString NewTeacherName(TEXT("이득우")); FProperty* NameProp = UTeacher::StaticClass()->FindPropertyByName(TEXT("Name")); // 속성 이름("Name")으로 검색해서 포인터를 가져옴 if (NameProp) { NameProp->GetValue_InContainer(Teacher, &CurrentTeacherName); UE_LOG(LogTemp, Log, TEXT("현재 선생님 이름: %s"), *CurrentTeacherName); // "이선생" (CDO 기본값) NameProp->SetValue_InContainer(Teacher, &NewTeacherName); UE_LOG(LogTemp, Log, TEXT("새로운 선생님 이름: %s"), *Teacher->GetName()); // "이득우" }

리플렉션을 통한 함수 호출
런타임에서 동작 중인 객체의 UFUNCTION 프로퍼티 중에서 DoLesson의 함수 포인터를 가져와 실행
Student->DoLesson(); // FindFunctionByName 함수를 통해 DoLesson 함수를 이름으로 검색해서 DoLessonFunc의 포인터를 가져옴 UFunction* DoLessonFunc = Teacher->GetClass()->FindFunctionByName(TEXT("DoLesson")); if (DoLessonFunc) // "DoLesson"이름의 함수를 찾았다면 { Teacher->ProcessEvent(DoLessonFunc, nullptr); // Teacher 인스턴스를 지정하고 ProcessEvent 함수를 이용해서 함수 포인터를 넘겨줌 }
Student.cpp
더보기
#include "Student.h" UStudent::UStudent() { Name = TEXT("이학생"); Year = 1; Id = 1; } void UStudent::DoLesson() { Super::DoLesson(); UE_LOG(LogTemp, Log, TEXT("%d학년 %d번 %s님이 수업을 듣습니다."), Year, Id, *Name); }
Teacher.cpp
더보기
#include "Teacher.h" UTeacher::UTeacher() { Name = TEXT("이선생"); Year = 3; Id = 1; } void UTeacher::DoLesson() { Super::DoLesson(); UE_LOG(LogTemp, Log, TEXT("%d년차 선생님 %s님이 수업을 강의합니다."), Year, *Name); }

정리: 언리얼 리플렉션 시스템의 활용
- 리플렉션 시스템을 사용해 언리얼 오브젝트의 특정 속성과 함수를 이름으로 검색할 수 있다.
- 리플렉션 시스템을 사용해 접근 지시자와 무관하게 속성값을 설정할 수 있다.
- 리플렉션 시스템을 사용해 언리얼 오브젝트의 함수를 호출할 수 있다.
언리얼 엔진의 기본 프레임웍은 리플렉션을 활용해 구축되어 있으므로,
언리얼 엔진을 이해하기 위해서는 리플렉션 시스템을 이해하는 것이 필요함.
'⭐ Unreal Engine > UE 개념정리 - 언리얼의 이해' 카테고리의 다른 글
[UE] 언리얼 C++ 설계 2 - 컴포지션 (0) | 2024.04.05 |
---|---|
[UE] 언리얼 C++ 설계 1 - 인터페이스 (0) | 2024.04.05 |
[UE] 언리얼 리플렉션 Unreal Reflection I (0) | 2024.03.18 |
[UE] 언리얼 오브젝트 시스템 (0) | 2024.03.18 |
[UE] 문자타입, 문자열 FString, FText, FString (0) | 2024.03.13 |
댓글
이 글 공유하기
다른 글
-
[UE] 언리얼 C++ 설계 2 - 컴포지션
[UE] 언리얼 C++ 설계 2 - 컴포지션
2024.04.05 -
[UE] 언리얼 C++ 설계 1 - 인터페이스
[UE] 언리얼 C++ 설계 1 - 인터페이스
2024.04.05 -
[UE] 언리얼 리플렉션 Unreal Reflection I
[UE] 언리얼 리플렉션 Unreal Reflection I
2024.03.18언리얼 오브젝트의 특징과 리플렉션 시스템의 동작원리를 이해하자. 언리얼 오브젝트의 처리 방식을 이해하고 사용예시를 분석하자. 인프런 이득우님의 '언리얼 프로그래밍 Part1 - 언리얼 C++의 이해' 강의를 참고하였습니다. 😎 [이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해] 강의 들으러 가기! 목차 언리얼 오브젝트 리플렉션 리플렉션(Reflection)은 프로그램이 실행시간에 자기 자신을 조사하는 기능이다. UPROPERTY()를 붙이는 기준 리플렉션 프로퍼티 변수는 언리얼 엔진의 시스템의 관리(=Garbage Collector)를 받는다. 반면에, 리플렉션 프로퍼티가 아닌 것은 해당 리플렉션에 의존하는 시스템 전부에 보이지 않는다.즉, 리플렉션 되지 않은 UObject … -
[UE] 언리얼 오브젝트 시스템
[UE] 언리얼 오브젝트 시스템
2024.03.18언리얼 오브젝트의 소개와 선언방법게임 프로그래밍이 가지는 특수성과 언리얼 오브젝트의 필요성의 이해언리얼 오브젝트의 선언과 엔진 내부 컴파일 과정의 학습 인프런 이득우님의 '언리얼 프로그래밍 Part1 - 언리얼 C++의 이해' 강의를 참고하였습니다. 😎 [이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해] 강의 들으러 가기! 목차 C++ 언어 게임 프로그래밍의 특수성 사용자: 쾌적한 경험을 위해 단일 컴퓨터에서 최대 성능을 뽑아내야 한다.개발자: 게임의 규모가 커질수록 방대하고 복잡한 기능을 안정적으로 관리해야 한다. C++ 언어의 단점 C++1970년대 개발하여 오래됨객체 지향 프로그래밍의 선두 주자현재까지 지속적으로 개선해왔지만, 익혀야 할 내용이 많음하드웨어에 직접 접근하…
댓글을 사용할 수 없습니다.