[UE] 리플렉션2022. 4. 30. 01:13
리플렉션
프로그램이 실행시간(런타임)에 자기 자신을 조사하는 기능
▶ 자기자신의 정보를 들여다본다.
① 런타임
우리가 코드를 짜고 빌드를 하게되면 컴파일을 하게 되는데
컴파일의 순서는 아래와 같다.
번역된 어셈블리는 우리가 미리 작성한 스크립트(소스파일) 기준으로 생성이 된다.
런타임 때( = 어셈블리가 동작할 때 )는 메서드가 호출되거나 필드의 값을 변경하는 것들이 모두 프로그래머가 빌드하기 전에 스크립트로 미리 작성해놓은 대로 실행된다.
즉, 런타임 때 동작하는 것들은 스크립트에 정의해놓은 일련의 작업일 뿐이다.
--> ex. ( C++ 스타일 )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
switch( selectType )
{
case 1:
{
cout << " A 값을 " + object.a + " 값으로 변경했습니다." <<endl;
}
break;
case 2:
{
cout << " B 값을 " + object.b + " 값으로 변경했습니다." <<endl;
}
break;
case 3:
{
cout << " C 값을 " + object.c + " 값으로 변경했습니다." <<endl;
}
break;
}
|
cs |
> 이 코드는 단순히 이미 알고있는, 미리 정의된 동작만 수행한다.
(case 1, 2, 3 ---> 케이스가 추가되면 상황에 따라 프로그래머가 작성해야한다.)
하지만!! 리플렉션을 사용하게 되면 형식(Type)에 정의된 필드나 메서드를 조사해서 값을 가져오거나 설정하거나 호출할 수 있게된다.
즉, 위의 예제처럼 일일히 하나씩 미리 구현할 필요가 없어진다.
--> ex. ( C# 스타일 - 리플렉션 코드 )
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
|
// GetType() : 오브젝트의 형식(Type)을 가져온다.
// GetField() : 형식(Type) 내의 필드 정보를 조사한다.
// Where((i) => i.FieldType == typeof(int)) : int 즉, 정수 형식 필드만 사용하겠다.
var _getField = myObject.GetType()
.GetField( BindingFlags.Instance | BindingFlags.Public )
.Where( (i) => i.FieldType == typeof(int) )
.ToArray();
// Console.ReadLine() : C# 에서 콘솔 입력 받는 표준 문법
int _userInputValue = Console.ReadLine();
if ( selectType >= 1 && selectType <= _getField.Length )
{
_getField[selectType - 1].SetValue(object, _userInputValue);
Log.Debug(" {0} 값을 {1} 값으로 변경했습니다. ", _getField[selectType - 1], _userInputValue);
}
// 런타임 때
// GetType() 예제로 정보를 가져와서
// GetField() 예제로 정보를 알아내서
// SetValue() 예제로 적절히 맞춰서 사용
|
cs |
위의 예제를 참조하면
런타임 때 코드가 직접 정보를 알아내서(알 수 있어서) 적절히 맞춰서 사용할 수 있다.
▶ 리플렉션
② 리플렉션의 장점
위의 예제에서 Class에 필드가 추가되거나 제거되거나 수정이 되어도
코드 부분은 이를 반영하여 결과를 유동적으로 표시할 수 있다는 것.
언리얼의 리플렉션
1.
에디터의 디테일 패널, 시리얼라이제이션, 가비지 콜렉션, 네트워크 리플리케이션, 블루프린트와 C++의 커뮤니케이션 등 다수의 시스템에 탑재되어 있다.
리플렉션은 JAVA, C# 에서는 기본적으로 제공하는 기능이지만 C++ 에서는 제공하지 않아서 언리얼에서 자체적으로 제공하며 C++ 클래스, 구조체, 함수 멤버변수, 열거형... 등 관련 정보를 수집/질의/조작하는 별도의 시스템이 구축되어 있다.
---> 이것을 언리얼 프로퍼티 시스템 이라고도 부르며, 매크로 함수 형태로 되어있다.
cf.
에디터의 디테일 패널 :
언리얼 에디터도 일종의 언리얼 어플리케이션이다. 그래서 리플렉션을 통해 에디터가 켜져있는 중에도 컴파일이 끝나면 디테일 패널이 갱신된다.
2.
리플렉션 기능이 적용됐으면하는 유형이나 프로퍼티에 특수한 주석을 달아주면 Unreal Hear Tool ( UHT )이 그 프로젝트를 컴파일 할 때 해당 정보를 수집한다.
단, 리플렉션이 있는 유형으로 처리하려면 헤더에 특수한 include 를 해주어야 한다.
---> #include "FileName.generated.h"
* 특수한 주석 :
UCLASS( ), USTRUCT( ), UENUM( ), EFUNCTION( ), UPROPERTY( ) ....
---> 이 매크로 각각은 유형 및 멤버 선언 전에 오며, 추가적인 키워드를 담을 수 있다. (EditAnywhere 등)
----------------------------
★ 주의할 점 !!
UCLASS( )
class A:
private:
int8 MyTeamCount;
리플렉션 클래스에 네이티브 변수를 넣을 수도 있다.
단, 리플렉션된 프로퍼티가 아닌 변수는 리플렉션된 값을 그대로 저장할 경우 ( 예를 들어, UObject* 와 같은 )
가비지 콜렉터가 레퍼런스를 확인할 수 없기에 조심해야한다.
출처:
https://kyoun.tistory.com/126
https://cs-solution.tistory.com/20?category=1046133
'Engine > Unreal' 카테고리의 다른 글
[UE] USceneComponent 와 PrimitiveComponent (0) | 2022.05.09 |
---|---|
[UE] 델리게이트와 이벤트 (0) | 2022.05.09 |
[UE] Unreal C++ 스크립트 규칙 (0) | 2022.05.07 |
[UE] 언리얼 오브젝트와 UClass (0) | 2022.05.01 |
[UE] 자주 사용하는 언리얼 함수/변수/매크로 (0) | 2022.04.23 |