강의 목표 :
- 언리얼 C+ 인터페이스 클래스를 사용해 보다 안정적으로 클래스를 설계하는 기법의 학습
강의 내용 :
- 클래스가 반드시 구현해야 하는 기능을 지정하는데 사용되는 인터페이스
- 언리얼 C++ 인터페이스는 두 개의 클래스를 생성한다.
- 언리얼 C++ 인터페이스는 추상 타입으로 강제되지 않고, 내부에 기본 함수를 구현할 수 있다.
[ ✔️인터페이스 ]
📍인터페이스란? :
모던 객체지향 설계에 사용되는 타입
객체를 설계한 클래스가 반드시 구현해야 할 행동을 지정하는데 활용된다.
"다형성(Polymorphism)" 의 구현, 의존성이 "분리(Decouple)" 된 설계에 유용하게 활용
C++은 기본적으로 다중상속을 지원하지만, 언리얼 C++의 인터페이스를 사용해 가급적 축소된 다중상속의 형태로 구현하는 것이 향후 유지보수에 도움된다.
📍언리얼 인터페이스 :
언리얼에서 인터페이스를 생성하면 두개의 클래스가 생성된다.
- U로 시작하는 "타입 클래스" : 해당 클래스에서 작업할 일 없음
- I로 시작하는 "인터페이스 클래스" : 인터페이스 관련 구성 및 구현 작업 진행
추상 타입으로만 선언할 수 있는 Java,C# 과 달리 언리얼 인터페이스는 내부적으로 C++의 클래스를 기반으로 구현되기에, 인터페이스에서도 기능 구현이 가능하다.
📍인터페이스를 활용한 오브젝트 설계 예시 :
- Actor : 월드에 배치된 모든 오브젝트 (움직이는 오브젝트와 안 움직이는 오브젝트 모두 포함)
- Pawn : 움직이는 오브젝트 (움직이는 오브젝트에 대한 특수기능 추가)
- Interface : 특정 기능을 반드시 구현하도록 강제한다.
Pawn 이 INavAgentInterface 를 상속받도록 하여 움직일때 반드시 길찾기 시스템을 사용하도록
📍소스코드 복사 :
다른 프로젝트의 소스코드를 복사해온 경우 언리얼 에디터에서 Refresh 해줘야 VS에서 추가된걸 확인할 수 있다.
헤더 파일의 언리얼 오브젝트 선언시 추가된 전처리 구문("objectreflection_api") 때문에 바로 사용할 수 없다.
해당 전처리 구문은 외부 모듈이 현재 언리얼 인터페이스 모듈 내의 클래스인 UMyGameInstance 를 접근할 수 있는지 지시하는 키워드이다.
해당 키워드가 정의되어 있지 않기 때문에 컴파일시 컴파일시 컴파일 에러가 발생한다.
(objectreflection = 복사해온 소스코드의 프로젝트의 이름)
프로젝트 생성시 기본적으로 생성되는 소스코드 중 하나인 "~GameModeBase.h" 에 들어가면 해당 프로젝트에 맞는 전치리 구문이 들어가 있는것을 확인할 수 있다.
해당 키워드를 복사해온 소스코드의 전처리 구문으로 덮어쓰기 해준다.
📍인터페이스 클래스 생성 :
"Add C++ Class → Common Class → Unreal Interface" 를 통해 생성가능
인터페이스 생성시 2개의 클래스(U, I)가 생성된다.
- UInterface 클래스 : 타입 정보를 보관하기위해서 생성한 클래스
- IInterface 클래스 : 인터페이스 관련 함수들과 기능을 구현하는 클래스, 실직적인 작업은 해당 클래스에서 한다.
인터페이스에는 상속받는 클래스들에게 구현을 강제할 함수를 순수 가상함수로 만들어준다.
만약 Interface 를 상속받았는데, 순수가상함수를 구현하지 않으면 아래와 같이 컴파일 에러가 발생한다.
언리얼 인터페이스의 경우 인터페이스내에 함수를 무조건 순수가상함수로 구현해줄 필요가 없다.
때문에 아래와 같이 인터페이스에서도 함수의 기능을 구현할 수 있지만, 이렇게되면 모던 객체지향에서 추구하는 방향과 거리가 멀긴하지만... (하위 클래스에 함수 구현 강제성이 사라짐)
편리한 형태를 선택해서 활용하면 된다.
클래스는 단일 상속만 가능하기에 Super 키워드를 통해 Interface에 구현된 DoLesson() 함수를 호출 할 수 없다.
때문에 아래와 같이 IInterface를 명시해줘야한다.
📍실습
수업 행동 관련 인터페이스 : ILessonInterface
수업에 반드시 참여하는 사람과 참여하지 않는 사람 구분
- 수업에 반드시 참여하는 사람 : Student, Teacher
- 수업에 참여하지 않는 학교 구성원 : Staff
코드 :
코드 :
#pragma region Interface
UE_LOG(LogTemp, Log, TEXT("======================"));
TArray<UPerson*> Persons = { NewObject<UStudent>(), NewObject<UTeacher>(), NewObject<UStaff>() };
for (const auto Person : Persons)
{
// 해당하는 Person 클래스가 Interface를 상속받은 경우 형변환 됨
// 상속받지 않은경우 형변환 안되기에 Cast 연산시 nullptr 반환
ILessonInterface* LessonInterface = Cast<ILessonInterface>(Person);
if (LessonInterface)
{
UE_LOG(LogTemp, Log, TEXT("%s님이 수업에 참여할 수 있습니다."), *Person->GetName());
LessonInterface->DoLesson();
}
else
{
UE_LOG(LogTemp, Log, TEXT("%s님이 수업에 참여할 수 없습니다."), *Person->GetName());
}
}
UE_LOG(LogTemp, Log, TEXT("======================"));
#pragma endregion
결과 :

================================
개인 공부 기록용 포스팅입니다.
댓글, 질문 환영해요~!
Unreal Engine Ver : 5.1.1
Refer : Inflearn_이득우의 언리얼 프로그램
================================
'Unreal > Inflearn' 카테고리의 다른 글
Part1.9 언리얼 C++ 설계 Ⅲ - 델리게이트(Delegate)⭕ (2) | 2024.04.11 |
---|---|
Part1.8 언리얼 C++ 설계 Ⅱ - 컴포지션⭕ (0) | 2024.04.09 |
Part1.6 언리얼 오브젝트 리플렉션 시스템 Ⅱ⭕ (0) | 2024.04.08 |
Part1.5 언리얼 오브젝트 리플렉션 시스템 Ⅰ⭕ (0) | 2024.04.08 |
Part1.4 언리얼 오브젝트 소개 ⭕ (0) | 2024.04.08 |