1편에 이어서 예제를 완성해보기.
예제를 통해, 리플렉션에 대해 알아보자.
어떤 학교에서 학생과 교수가 함께 수업하는 상황의 구현
학교 정보는 GameInstance에서 지정
인물 클래스 (부모)
1. Person.h
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "Person.generated.h"
/**
*
*/
UCLASS()
class OBJECTREFLECTION_API UPerson : public UObject
{
GENERATED_BODY()
public:
UFUNCTION()
virtual void DoLesson();
//Getter , Setter
const FString& GetName() const;
void SetName(const FString& InName);
protected:
UPROPERTY()
FString Name;
UPROPERTY()
int32 Year;
private:
};
1. Person.cpp
#include "Person.h"
UPerson::UPerson()
{
Name = TEXT("홍길동");
Year = 1;
}
void UPerson::OnLesson()
{
UE_LOG(LogTemp, Log, TEXT("%s님이 수업에 참여합니다."), *Name);
}
const FString& UPerson::GetName() const
{
return Name;
}
void UPerson::SetName(const FString& InName)
{
Name = InName;
}
2. 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;
};
2. 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);
}
3. 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;
};
3. 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);
}
기본 클래스 설정은 끝냈고 cpp 파일에 한글을 출력하므로 모든 cpp 파일 Save as -> Save with encoding 에서 UTF8설정으로 바꿔야 제대로 출력이 된다.
MyGameInstance.h
1. Student,Teacher 헤더파일 추가
2. 주의 : 원래 헤더보다 위에 다른 헤더파일 선언이 되어있으면 오류
#include "MyGameInstance.h"
#include "UObject/Class.h"
#include "Student.h"
#include "Teacher.h"
UMyGameInstance::UMyGameInstance()
{
SchoolName = TEXT("기본학교");
}
void UMyGameInstance::Init()
{
Super::Init();
UE_LOG(LogTemp, Log, TEXT("=========================="));
UClass* ClassRuntime = GetClass();
UClass* ClassCompile = UMyGameInstance::StaticClass();
//check(ClassRuntime == ClassCompile);
//ensure(ClassRuntime != ClassCompile);
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;
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());
}
//리플렉션 시스템으로 함수를 실행하는 법
Student->DoLesson();
UFunction* DoLessonFunc = Teacher->GetClass()->FindFunctionByName(TEXT("DoLesson"));
if (DoLessonFunc)
{
Teacher->ProcessEvent(DoLessonFunc, nullptr);
}
}