블루프린트에서의 상속 기본 개념
부모와 자식 블루프린트가 기능을 물려받는 원리를 이해하고 공통 로직 재사용과 오버라이드 방법을 익힙니다.
이제 액터와 컴포넌트의 역할에 대해 이해하셨으니, 객체 지향 프로그래밍(Object-Oriented Programming, OOP)의 핵심 개념 중 하나인 상속(Inheritance)에 대해 알아보겠습니다.
상속은 블루프린트 개발에서 재사용성과 확장성을 극대화하는 데 필수적인 개념입니다.
상속이란 무엇인가?
상속은 기존 클래스(Class)의 속성(변수)과 기능(함수, 이벤트)을 새로운 클래스가 물려받는 개념입니다.
기존 클래스는 부모 클래스(Parent/Base Class), 새로 물려받는 클래스는 자식 클래스(Child/Derived Class)라고 부릅니다.
비유로 보면, 자동차라는 부모 클래스에는 움직인다, 탑승할 수 있다 같은 공통 기능이 있습니다.
여기서 스포츠카나 트럭을 자식 클래스로 만들면, 공통 기능을 다시 작성할 필요 없이 상속받고 각 클래스의 특징(예: 빠른 가속, 적재 기능)만 추가하면 됩니다.
액터 블루프린트와 컴포넌트 블루프린트는 모두 클래스를 정의하지만, 각각 호환되는 부모 계층 안에서 상속해야 합니다. 액터를 컴포넌트의 자식으로 만드는 식으로 두 계층을 섞을 수는 없습니다.
블루프린트에서의 상속
언리얼 엔진의 블루프린트는 객체 지향 프로그래밍의 상속 개념을 시각적으로 구현하고 있습니다.
특정 액터 블루프린트를 다른 액터 블루프린트의 자식으로 만들면 부모의 구성과 동작을 상속받습니다. 다만 변수·함수의 접근 지정과 편집 허용 여부에 따라 자식에서 직접 접근하거나 변경할 수 있는 범위가 다릅니다.
상속의 이점코드 재사용성: 이미 구현된 기능을 다시 만들 필요가 없어 개발 시간을 단축하고 오류 발생 가능성을 줄입니다.
유지보수 용이성: 부모에서 상속된 구현을 수정하면 이를 그대로 사용하는 자식에도 반영됩니다. 자식이 재정의한 함수나 별도로 덮어쓴 기본값은 함께 확인해야 합니다.
이는 대규모 프로젝트에서 일관성을 유지하고 유지보수를 효율적으로 만드는 데 큰 도움이 됩니다.
확장성: 기존 기능을 건드리지 않고 새로운 기능을 추가하거나, 물려받은 기능을 자식 클래스에서 오버라이드(재정의)하여 특정 동작을 변경할 수 있습니다.
상속 관계 만들기: 부모 클래스 선택
새로운 블루프린트 클래스를 생성할 때, 가장 먼저 부모 클래스 선택(Pick Parent Class) 창이 나타납니다.
여기서 선택하는 클래스가 새로 만들 블루프린트의 부모 클래스가 됩니다.
- 예를 들어, 모든 문이 공통적으로 가지는 열림/닫힘 기능을
BP_Door_Base라는 부모 블루프린트에 구현했다고 가정해 봅시다. - 이제 나무 문과 철 문이라는 두 가지 종류의 문을 만들고 싶다면,
BP_Door_Wood와BP_Door_Metal이라는 새로운 액터 블루프린트를 생성할 때, 부모 클래스로BP_Door_Base를 선택할 수 있습니다. - 이렇게 생성된
BP_Door_Wood와BP_Door_Metal은BP_Door_Base가 가진 열림/닫힘 기능과 모든 변수, 컴포넌트를 물려받게 됩니다. 여기에 각 자식 클래스만의 시각적 요소(나무 모델, 철 모델)나 추가적인 기능(철 문은 자물쇠 기능)을 더할 수 있습니다.
상속된 기능 오버라이드(Override)하기
자식 클래스에서는 부모 클래스에서 물려받은 함수나 이벤트를 오버라이드(Override, 재정의)하여 자신만의 고유한 방식으로 동작하도록 만들 수 있습니다.
부모의 기본 동작을 대체하거나, 부모 호출에 자식의 처리를 덧붙일 때 사용합니다. 오버라이드한 그래프에서 부모 호출을 생략하면 해당 부모 구현이 자동으로 실행되는 것은 아닙니다.
오버라이드 방법자식 블루프린트 에디터를 엽니다.
좌측 함수(Functions) 패널 또는 이벤트 그래프에서 오버라이드하고 싶은 함수나 이벤트를 찾습니다.
함수 패널의 Override 목록에서 재정의할 수 있는 부모 함수를 선택합니다. 출력이 없는 함수 등은 이벤트 형태로 나타날 수 있으므로 생성된 함수 또는 이벤트의 진입점에 로직을 연결합니다.
이벤트 그래프의 경우, 예를 들어 Event BeginPlay와 같이 이미 존재하는 기본 이벤트를 선택합니다.
오버라이드된 함수 또는 이벤트의 그래프에 새로운 로직을 구현합니다.
Parent Call 노드: 오버라이드된 함수나 이벤트 내부에서 Parent Call 노드를 사용하여 부모 클래스의 원래 로직을 호출할 수 있습니다.
예를 들어, 자식 클래스에서 추가적인 로직을 실행하기 전에 부모의 BeginPlay 로직을 먼저 실행하고 싶을 때 유용합니다.
오버라이드를 설계할 때는 자식 블루프린트가 무엇을 그대로 물려받고, 어떤 동작을 새로 정의하며, 부모의 기본 로직까지 함께 실행할지 차례대로 판단하는 것이 좋습니다.
예시: 오버라이드를 통한 특수 문 만들기BP_Door_Base의 OpenDoor 함수에 문이 열릴 때 문이 열립니다!라고 출력하는 로직이 있다고 가정해 봅시다.
아직 이 부모 에셋이 없다면 Actor 블루프린트 BP_Door_Base를 만들고, 출력 매개변수가 없는 OpenDoor에 Print String 하나만 연결해 부모 문구를 출력하도록 준비합니다. 컴파일·저장한 뒤 이 클래스를 부모로 삼아 BP_Door_Wood를 만듭니다. 이번 목표는 두 출력의 실행 범위 확인이며 실제 문 메시나 애니메이션은 필요하지 않습니다. 자식 인스턴스를 레벨에 하나 배치하고 그 자식의 BeginPlay에서 OpenDoor를 한 번 호출하면 아래 재정의 결과를 확인할 수 있습니다.
BP_Door_Wood (부모: BP_Door_Base) 블루프린트를 엽니다.
좌측 함수 패널의 Override 목록에서 OpenDoor를 선택합니다. 생성된 함수 또는 이벤트 그래프를 사용합니다.
OpenDoor 오버라이드 그래프에서 Print String 노드를 추가하여 나무 문이 열립니다!라고 출력하도록 설정합니다.
만약 부모의 문이 열립니다! 메시지도 함께 출력하고 싶다면, 진입점에서 Add Call to Parent Function으로 Parent: OpenDoor를 만들고, 실행 선을 부모 호출에서 Print String으로 연결합니다.
오버라이드에서 부모 구현을 호출할지 선택합니다
서로 독립적인 세 구현 중 부모 호출을 연결한 실제 경로에서 자식 진입→Parent OpenDoor 출력→자식 출력 순서를 추적할 수 있다. 재정의 없음/부모 호출 없음 비교는 위 관계도와 표에 유지한다.
INHERIT · OVERRIDE · PARENT CALL
오버라이드에서 부모 구현을 호출할지 선택합니다
부모 BP_Door_Base의 OpenDoor가 “문이 열립니다!”를 출력하는 예입니다. 자식 BP_Door_Wood의 구현 방식에 따라 출력 결과가 달라집니다.
재정의된 그래프가 부모 구현을 자동 실행하지는 않습니다. 공통 처리가 필요하면 부모 호출을 연결하고 자식 처리와의 순서를 정합니다. 비교의 세 경로 사이에는 실행선이 없습니다.
이 예의 조건
- 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
- 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| 자식 진입 부모 호출을 연결한 override 사본을 실행한다. |
|
|
| Parent 호출 명시한 Parent OpenDoor가 부모 출력을 수행한다. |
|
|
| 자식 후속 돌아온 뒤 자식 출력을 수행한다. |
|
|
오버라이드에서 부모 구현을 호출할지 선택합니다
서로 독립적인 세 구현 중 부모 호출을 연결한 실제 경로에서 자식 진입→Parent OpenDoor 출력→자식 출력 순서를 추적할 수 있다. 재정의 없음/부모 호출 없음 비교는 위 관계도와 표에 유지한다.
INHERIT · OVERRIDE · PARENT CALL
오버라이드에서 부모 구현을 호출할지 선택합니다
부모 BP_Door_Base의 OpenDoor가 “문이 열립니다!”를 출력하는 예입니다. 자식 BP_Door_Wood의 구현 방식에 따라 출력 결과가 달라집니다.
재정의된 그래프가 부모 구현을 자동 실행하지는 않습니다. 공통 처리가 필요하면 부모 호출을 연결하고 자식 처리와의 순서를 정합니다. 비교의 세 경로 사이에는 실행선이 없습니다.
이 예의 조건
- 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
- 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| 자식 진입 부모 호출을 연결한 override 사본을 실행한다. |
|
|
| Parent 호출 명시한 Parent OpenDoor가 부모 출력을 수행한다. |
|
|
| 자식 후속 돌아온 뒤 자식 출력을 수행한다. |
|
|
부모 호출을 뺀 결과 예상하기
부모 OpenDoor의 문구를 “공통 문 처리”로 바꾸었습니다. 자식 OpenDoor에는 부모 호출 없이 “나무 문 처리”를 출력하는 노드만 있고, 그 자식 인스턴스에서 OpenDoor를 한 번 호출합니다. 공통 문구도 함께 출력될까요?
상속한 정의와 재정의한 실행을 구분하기
자식 문구만 출력됩니다. 부모 함수의 수정이 자식의 별도 재정의 그래프를 실행시키거나 부모 호출을 추가하지는 않습니다. 공통 처리도 필요하다면 자식 그래프에 Parent: OpenDoor를 연결하고, 자식 처리 앞뒤 중 필요한 순서를 정합니다. 본문의 원래 두 문구 예제와 이번 변형의 문구를 구분해 확인하세요.
이처럼 상속은 블루프린트 기반의 게임 개발에서 강력한 구조화 및 재사용 도구입니다.
복잡한 시스템을 설계할 때, 공통된 부분은 부모 클래스에 정의하고, 특수한 부분은 자식 클래스에서 확장하거나 재정의함으로써 효율적인 개발을 가능하게 합니다.
이번 절에서는 블루프린트에서의 상속 개념, 그 이점, 그리고 오버라이드 방법에 대해 알아보았습니다.
상속은 언리얼 엔진에서 객체 지향 설계를 실현하는 핵심적인 방법이며, 공통 로직을 재사용하고 자식 블루프린트에서 차이를 관리할 때 중요합니다.