블루프린트 인터페이스 활용
지금까지 액터와 컴포넌트, 그리고 상속을 통해 객체 지향의 기본 원리를 블루프린트에서 어떻게 적용하는지 알아보았습니다. 이번 절에서는 객체 지향 설계의 또 다른 강력한 도구인 블루프린트 인터페이스(Blueprint Interface) 에 대해 설명드리겠습니다. 인터페이스는 상속과는 또 다른 방식으로 블루프린트 간의 유연한 통신을 가능하게 하며, 느슨한 결합(Loose Coupling)을 통해 확장성과 유지보수성을 크게 향상시킵니다.
인터페이스란 무엇인가?
일상생활의 비유를 들어 설명해 볼까요? 여러분이 스마트폰 충전기(인터페이스)를 가지고 있다고 생각해봅시다. 이 충전기는 어떤 종류의 스마트폰이든 상관없이 특정 포트(USB-C, 라이트닝 등)만 가지고 있다면 충전할 수 있습니다. 충전기는 '충전한다'는 기능만 정의할 뿐, 그 기능을 어떤 스마트폰이 어떻게 구현하는지는 신경 쓰지 않습니다.
블루프린트 인터페이스도 이와 유사합니다. 인터페이스는 특정 기능의 이름만 정의하고, 그 기능을 어떻게 구현할지는 해당 인터페이스를 '구현(Implement)'하는 블루프린트 클래스에 맡깁니다. 인터페이스 자체는 어떠한 로직이나 변수도 포함하지 않습니다. 오직 '이러한 기능이 존재한다'는 약속만을 담고 있습니다.
인터페이스가 왜 필요한가?
상속은 "A는 B이다 (A is a B)"라는 '부모-자식' 관계를 형성합니다. 예를 들어, BP_SportsCar
는 BP_Car
이다. 이는 매우 강력하지만, 한 가지 제약이 있습니다. 블루프린트는 단일 상속(Single Inheritance) 만을 지원합니다. 즉, 하나의 블루프린트는 오직 하나의 부모 블루프린트만 가질 수 있습니다.
하지만 게임 개발에서는 여러 블루프린트가 서로 다른 종류의 '기능'을 공유해야 하는 경우가 많습니다. 예를 들어, BP_Door
(문), BP_Lever
(레버), BP_Button
(버튼)과 같은 액터들이 모두 '상호작용'이라는 공통된 기능을 가져야 한다고 가정해봅시다. 이들을 모두 같은 부모 클래스로 묶는 것은 논리적으로 맞지 않을 수 있습니다. 문은 레버가 아니고, 레버는 버튼이 아니니까요.
이럴 때 인터페이스가 해결책이 됩니다. 이 세 가지 액터(문, 레버, 버튼)는 모두 BPI_Interactable
(상호작용 가능 인터페이스)를 '구현'할 수 있습니다. 각 액터는 BPI_Interactable
이 정의한 Interact
(상호작용) 기능을 자신만의 방식으로 구현합니다. 문은 열리고, 레버는 작동하고, 버튼은 눌리는 식으로 말이죠.
인터페이스는 "A는 B를 할 수 있다 (A can do B)"라는 '능력' 관계를 정의합니다. 이를 통해 블루프린트 간의 느슨한 결합을 가능하게 합니다. 특정 블루프린트가 어떤 인터페이스를 구현했는지 확인만 하면, 그 블루프린트가 해당 인터페이스에 정의된 기능을 가지고 있다고 확신하고 호출할 수 있습니다. 이는 시스템의 유연성을 극대화하고, 나중에 새로운 상호작용 가능한 오브젝트를 추가할 때 기존 코드를 수정할 필요 없이 인터페이스만 구현하면 되므로 확장성에도 매우 유리합니다.
블루프린트 인터페이스 생성 및 정의
인터페이스 생성하기
- 콘텐츠 브라우저(Content Browser) 에서 마우스 오른쪽 버튼을 클릭합니다.
블루프린트(Blueprints)
>블루프린트 인터페이스(Blueprint Interface)
를 선택합니다.- 이름을 지정합니다. (예:
BPI_Interactable
- 일반적으로 'BPI_' 접두사를 사용합니다.) - 생성된 인터페이스 에셋을 더블클릭하여 인터페이스 에디터를 엽니다.
인터페이스 함수 정의하기
- 인터페이스 에디터의 좌측
함수(Functions)
패널에서+
버튼을 클릭하여 새로운 함수를 추가합니다. - 함수 이름을 지정합니다. (예:
Interact
) - 이 함수에 필요한 입력(Inputs) 및 출력(Outputs) 매개변수를 디테일 패널에서 추가합니다. (예:
Interact
함수는InteractingActor
(Actor Reference 타입)이라는 입력 핀을 가질 수 있습니다.) - 참고: 인터페이스 함수에는 로직을 구현할 수 있는 그래프가 없습니다. 오직 함수의 이름과 입출력 매개변수만 정의합니다.
컴파일 및 저장: 인터페이스를 정의한 후에는 반드시 컴파일하고 저장해야 합니다.
인터페이스 구현 및 활용
이제 생성한 인터페이스를 실제 액터 블루프린트에서 '구현'하고 '호출'해 봅시다.
액터 블루프린트에 인터페이스 구현하기
- 인터페이스 기능을 추가하고 싶은 액터 블루프린트(예:
BP_Door
)를 엽니다. - 블루프린트 에디터의 상단 툴바에서
클래스 세팅(Class Settings)
버튼을 클릭합니다. - 디테일 패널의
인터페이스(Interfaces)
섹션에서Implemented Interfaces
옆의+ 추가(+ Add)
버튼을 클릭합니다. - 목록에서 여러분이 만든 인터페이스(예:
BPI_Interactable
)를 검색하여 선택합니다. - 이제 블루프린트를 컴파일하면 좌측 함수(Functions) 패널에
인터페이스(Interfaces)
섹션이 새로 생기고, 그 아래에Interact
함수가 나타난 것을 볼 수 있습니다.
인터페이스 함수 오버라이드(구현)하기
- 좌측 함수 패널의
인터페이스
섹션 아래Interact
함수 위에서 마우스 오른쪽 버튼을 클릭하고이벤트 구현(Implement Event)
을 선택합니다. - 이벤트 그래프에
Event Interact
노드가 생성됩니다. 이제 이 이벤트 노드의 실행 핀 뒤에 이 액터가Interact
되었을 때 수행할 실제 로직을 구현합니다. - 예시:
Print String
노드를 연결하여 "문이 상호작용되었습니다!"라고 출력하도록 설정하고, 문을 열리는 애니메이션을 재생하는 로직을 추가할 수 있습니다. - 블루프린트를 컴파일하고 저장합니다.
인터페이스 메시지 호출하기
- 이제 다른 블루프린트(예: 플레이어 캐릭터 블루프린트)에서 이
Interact
기능을 호출해봅시다. - 플레이어 캐릭터 블루프린트의 이벤트 그래프에서, 예를 들어
E
키를 눌렀을 때 특정 액터와 상호작용하는 로직을 만든다고 가정합니다. Event E
키 입력 노드를 추가합니다.- 플레이어가 보고 있는 액터나 겹쳐진 액터를 가져오는 로직을 만듭니다. (예:
Line Trace By Channel
또는Get Overlapping Actors
사용) - 가져온 액터 레퍼런스 핀에서 드래그하여 마우스 오른쪽 버튼을 클릭하고, 여러분의 인터페이스 함수 이름(예:
Interact
)을 검색합니다. 이때,Message
가 붙은 노드를 선택해야 합니다. (예:Interact (Message)
) Interact (Message)
노드는 대상 액터가BPI_Interactable
인터페이스를 구현했는지 자동으로 확인하고, 구현했다면 해당 액터의Event Interact
로직을 실행시킵니다.Target
핀에는 상호작용할 액터 레퍼런스를 연결하고, 필요한 경우 입력 매개변수를 연결합니다.
이 방식의 장점은, Interact (Message)
노드를 연결할 때 대상 액터가 BP_Door
인지, BP_Lever
인지, BP_Button
인지 명시적으로 알 필요가 없다는 것입니다. 그저 BPI_Interactable
인터페이스를 구현했는지 여부만 중요합니다.
인터페이스 사용의 이점 정리
- 다형성(Polymorphism) 구현: 하나의 인터페이스 메시지 호출로, 다양한 종류의 블루프린트가 각자 자신만의 방식으로 기능을 수행할 수 있게 합니다.
- 느슨한 결합(Loose Coupling): 블루프린트 간의 의존성을 줄여줍니다. 호출하는 쪽은 특정 클래스에 묶이지 않고, 인터페이스만 알면 되므로 시스템 변경에 유연하게 대처할 수 있습니다.
- 확장성: 새로운 기능이 필요할 때, 기존 인터페이스에 함수를 추가하거나, 새로운 클래스가 기존 인터페이스를 구현하기만 하면 됩니다.
- 협업 효율성: 팀원 간에 기능의 '계약'을 명확히 정의할 수 있어, 각자 독립적으로 개발하고 나중에 쉽게 통합할 수 있습니다.
블루프린트 인터페이스는 복잡한 게임 시스템을 설계하고, 여러 블루프린트가 서로 유기적으로 상호작용하게 만들 때 매우 유용한 고급 도구입니다. 처음에는 어렵게 느껴질 수 있지만, 인터페이스를 활용하기 시작하면 블루프린트 코드의 유지보수성과 확장성이 크게 향상되는 것을 경험하실 수 있을 것입니다.
이번 절에서는 블루프린트 인터페이스의 개념, 생성 및 활용 방법, 그리고 상속과의 차이점에 대해 알아보았습니다. 인터페이스는 블루프린트의 객체 지향적 설계를 한 단계 더 발전시키는 중요한 요소입니다.