Unreal5 기초 리플렉션 시스템2

이승한·2024년 1월 12일
0

Unreal5

목록 보기
4/11

1편에 이어서 예제를 완성해보기.

1편 링크

예제를 통해, 리플렉션에 대해 알아보자.

어떤 학교에서 학생과 교수가 함께 수업하는 상황의 구현
학교 정보는 GameInstance에서 지정
인물 클래스 (부모)

  • Name(이름)
  • Year(연차)
  • DoLesson 가상 함수
  1. 학생 클래스
  • id (학번)
  • DoLesson 수업을 듣는 행동
  1. 선생 클래스
  • id (사번)
  • DoLesson 수업을 가르치는 행동

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

  • 주의 : 다른 헤더파일을 include 할 때 generated.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);
	}
}

0개의 댓글