언리얼 오브젝트 리플렉션 시스템을 사용해 언리얼 오브젝트를 다루는 방법
리플렉션 시스템을 사용하면
- 언리얼 오브젝트의 특정 속성과 함수를 이름으로 검색할 수 있음
- 접근 지시자와 무관하게 값을 설정할 수 있음
- 언리얼 오브젝트의 함수를 호출할 수 있음
리플렉션 시스템을 반드시 사용하는 것이 바람직한지는 사용하는 사람에 따라 다르나,
언리얼 엔진의 기본 프레임웍은 리플렉션을 활용해 구축되어 있으므로 언리얼 엔진을 이해하기 위해서는
리플렉션 시스템을 이해해야함
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "Person.generated.h"
/**
*
*/
UCLASS()
class OBJECTREFLECTION_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;
private:
};
Person.h
// Fill out your copyright notice in the Description page of Project Settings.
#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;
}
Person.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "Person.h"
#include "Student.generated.h"
//언리얼 오브젝트를 선언할 때는 반드시 .generated.h가 가장 밑에 include되어야함
/**
*
*/
UCLASS()
class OBJECTREFLECTION_API UStudent : public UPerson
{
GENERATED_BODY()
public:
UStudent();
virtual void DoLesson() override;
private:
UPROPERTY()
int32 Id;
};
Student.h
// Fill out your copyright notice in the Description page of Project Settings.
#include "Student.h"
UStudent::UStudent()
{
Name = TEXT("이학생");
Year = 1;
Id = 1;
//기본값을 설정했으면 CDO가 다시 생성되어야하기 때문에
//미리 컴파일해주는 것이 좋다
}
void UStudent::DoLesson()
{
Super::DoLesson();
UE_LOG(LogTemp, Log, TEXT("%d학년 %d번 %s님이 수업을 듣습니다."), Year, Id, *Name); //인코딩 변경
}
Student.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#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:
int32 Id;
};
Teacher.h
// Fill out your copyright notice in the Description page of Project Settings.
#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);
}
Teacher.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyGameInstance.h"
//현재 구현하고자 하는 언리얼 오브젝트의 헤더가 반드시 가장 위에 있어야함
#include "Student.h"
#include "Teacher.h"
UMyGameInstance::UMyGameInstance() //생성자
{
SchoolName = TEXT("기본학교"); //CDO 기본값 설정
}
void UMyGameInstance::Init()
{
Super::Init(); //원래 로직 실행
UStudent* Student = NewObject<UStudent>(); //언리얼 오브젝트이기 때문에 new가 아니라 NewObject로 생성
UTeacher* Teacher = NewObject<UTeacher>();
//구현해둔 getter, setter를 이용해 값을 가져오는 방법
Student->SetName(TEXT("학생1"));
UE_LOG(LogTemp, Log, TEXT("새로운 학생 이름 %s"), *Student->GetName());
//리플렉션을 활용해 값을 가져오는 방법
FString CurrentTeacherName;
FProperty* NameProp = UTeacher::StaticClass()->FindPropertyByName(TEXT("Name")); //클래스의 속성
if (NameProp) //값이 있다면. 없다면 null로 진입하지 않음
{
//GetValue_InContainer를 사용해 이 속성에 대해서 지정한 인스턴스의 값을 빼올 수 있음
//Teacher가 가지고 있는 객체의 속성 중 이름 속성값을 가져와야함.
NameProp->GetValue_InContainer(Teacher, &CurrentTeacherName);
UE_LOG(LogTemp, Log, TEXT("현재 선생님 이름 %s"), *CurrentTeacherName);
}
}
MyGameInstance.cpp
학생 이름은 getter, setter를 이용,
선생님 이름은 언리얼 리플렉션 시스템을 이용해 protected로 보호받고 있는 프로퍼티 값을 가져옴
//리플렉션을 활용해 값을 가져오는 방법
FString CurrentTeacherName;
FString NewTeacherName(TEXT("이득우"));
FProperty* NameProp = UTeacher::StaticClass()->FindPropertyByName(TEXT("Name")); //클래스의 속성
if (NameProp) //값이 있다면. 없다면 null로 진입하지 않음
{
//GetValue_InContainer를 사용해 이 속성에 대해서 지정한 인스턴스의 값을 빼올 수 있음
//Teacher가 가지고 있는 객체의 속성 중 이름 속성값을 가져와야함.
NameProp->GetValue_InContainer(Teacher, &CurrentTeacherName);
UE_LOG(LogTemp, Log, TEXT("현재 선생님 이름 %s"), *CurrentTeacherName);
//SetValue_InContainer를 사용해 이 속성에 대해서 지정한 인스턴스의 값을 변경할 수 있음
NameProp->SetValue_InContainer(Teacher, &NewTeacherName);
UE_LOG(LogTemp, Log, TEXT("새로운 선생님 이름 %s"), *Teacher->GetName());
}
리플렉션 시스템을 사용해 값 변경
UE_LOG(LogTemp, Log, TEXT("========================="));
//함수실행
Student->DoLesson();
//리플렉션을 활용해 함수실행
UFUNCTION()
UFunction* DoLessonFunc = Teacher->GetClass()->FindFunctionByName(TEXT("DoLesson"));
if (DoLessonFunc)
{
//함수를 찾았다면 ProcessEvent를 사용해 함수포인터를 넘겨주고 인자가 없기 때문에 null을 넣어준다
Teacher->ProcessEvent(DoLessonFunc, nullptr);
}
리플렉션 시스템을 사용해 함수 호출
이득우의 언리얼 프로그래밍 Part1 | 인프런
이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해 강의 | 이득우 - 인프런
이득우 | 대기업 현업자들이 수강하는 언리얼 C++ 프로그래밍 전문 과정입니다. 언리얼 엔진 프로그래머라면 게임 개발전에 반드시 알아야 하는 언리얼 C++ 기초에 대해 알려드립니다., [사진] 언
www.inflearn.com
'게임 개발 > 언리얼 C++' 카테고리의 다른 글
언리얼C++ - 컴포지션(Composition) (2) | 2024.11.15 |
---|---|
언리얼C++ - 인터페이스(Interface) (2) | 2024.11.14 |
언리얼C++ - 언리얼 오브젝트 리플렉션 시스템 1 (6) | 2024.11.12 |
언리얼C++ - 언리얼 오브젝트 기초 (0) | 2024.11.11 |
언리얼C++ - 기본타입과 문자열 (2) | 2024.11.10 |