Character의 공격 방식에 따라서 크게 검을 휘두르는 "Sword" 공격 방식과 "Wizard(마법)" 공격 방식을 구현했습니다. 우리는 OOP를 위해 상위 클래스 혹은 인터페이스 클래스 "Weapon (공격 무기)"를 구현해보겠습니다. 잘 알다시피, C++의 인터페이스 클래스는 자세한 "구현"이 없는 순수 가상 메서드를 정의해두어 이를 상속하는 하위 클래스들이 순수 가상 메서드를 직접 오버라이딩하는 방식입니다. 말 그대로, "인터페이스"만 제공하는 클래스죠!
2. Interface 생성 및 구현
BPI_Weapon
1. BPI_Weapon, 인터페이스 생성
Unreal에서 제공하는 "Interface"를 생성하고, 이를 상속하는 "Sword" 혹은 "Wizard" 클래스, 그 외 하위 클래스들은 인터페이스 클래스의 함수들을 정의합니다. 이때, BPI_Weapon을 C++의 정통적인 인터페이스 클래스라고 생각하기 보다, 말 그대로 하위 클래가 아닌 몇 개의 클래스들이 공통적으로 사용하는 프로퍼티 혹은 행동 집합을 모아놓는 "인터페이스"이자, 하위 클래스들이 상속도 가능한 혼합적인 형태로 보입니다.
오버라이딩
1. 인터페이스 메서드 정의
BP_Player의 이벤트 그래프 "인터페이스" 항목의 함수들
1. 인터페이스의 함수 목록
BPI_Weapon에서 생성한 인터페이스 함수들의 목록은 블루프린트 에디터 왼쪽 하단에서 발견할 수 있습니다.
2. 인터페이스 함수 오버라이딩
인터페이스 목록의 함수들을 용도에 맞게 정의해 주어야 합니다.
Weapon 블루프린트 클래스
1. Weapon 블루프린트 생성
BP_Weapon 생성 화면
2. BP_Weapon으로 BPI_Weapon의 함수들 가져오기
BP_Weapon의 함수 목록
앞서, BPI_Weapon에서 생성한 함수 목록들을 BP_Player에서 오버라이딩 했습니다. BP_Weapon은 오버라이딩한 인터페이스 함수들을 동명의 함수 내부에서 호출해줍니다. 부가적으로, 추후에 구현할 Weapon 변경 관련 이벤트들을 위해서 공격 방식 클래스들 중 가장 상위 클래스인 BP_Weapon에서 "On Selected(선택된 무기)" 커스텀 이벤트와 "OffSelected (선택 해제된 무기)" 커스텀 이벤트를 미리 생성해 둡니다.
3. 인터페이스 함수 호출
BP_Weapon의 GetState 함수 정의부
1. Get Owner
무기의 소유자, 즉 BP_Player를 호출하여 "인터페이스 함수"의 오버라이딩 여부를 확인합니다.
2. Does Implement Interface
단순히, Test Object에서 인터페이스를 정의했는지 체크하기 위함입니다.
3. Get Weapon State
Does Implement Interface 노드가 "True"를 리턴하면 미리 BP_Player에서 구현한 인터페이스 함수들을 호출하도록 합니다.
4. BP_Player -> BP_Weapon 옮겨지는 함수들
BP_Weapon의 CanAttack 함수 구현부BP_Weapon의 SendDamage(Apply Damage) 함수 구현부
1. CanAttack 함수
BP_Player에서 미리 구현했던 "공격 가능 여부"를 체크하는 "CanAttack" 함수를 BP_Weapon으로 옮깁니다.
2. SendDamage 함수
BP_Sword에서 미리 구현했던 "Damage 전달" 관련 이벤트를 BP_Weapon의 Send Damage 함수로 옮깁니다.
Combo, 콤보 클래스
1. 콤보 클래스 생성 및 부모 클래스 세팅
BP_Combo 블루프린트 에디터 창
클래스 세팅 -> Parent Class : BP_Weapon으로 변경합니다.
2. BP_Player의 Combo관련 변수들 -> BP_Combo
BP_Combo의 변수 목록
BP_Player의 "Combo" 관련 변수들을 모두 BP_Combo로 옮깁니다.
1. Combo Table : Combo 애님 몽타주 정보를 담고 있는 데이터 테이블 2. Combo Montages : Combo Table로부터 가져온 몽타주 정보를 담고 있는 구조체 3. Exist Next Combo 4. Enable Next Combo 5. Last Combo
3. BP_Player의 Load Sword Combo Table 이벤트 그룹 가져오기
BP_Player의 Load Combo Table 이벤트 그룹 -> BP_Combo의 BeginPlay 이벤트로 이전
앞서 BP_Player에서 정의한 Combo 애님 몽타주 애셋 정보들을 Load 하는 이벤트를 BP_Combo로 가져와야겠죠! BP_Combo도 시작과 동시에 필요하기 때문에, BeginPlay이벤트로 구현합니다.
4. BP_Player의 Attacking Event -> Sword Event 그룹 가져오기
BP_Combo의 이벤트 그래프 화면
미리 BP_Player에서 구현한 Sword의 일반 공격 및 콤보 공격 관련 이벤트 그룹을 모두 BP_Combo로 이전합니다. 더불어, 기존의 노드들 중 우리가 BPI_Weapon을 통해 생성한 인터페이스 함수 목록들과 기능이 중복되는 노드들을 발견할 수 있습니다. "Set Can Move"와 "Set State"는 인터페이스 함수들로 대체하도록 합니다.
5. BP_Player의 Play Combo Montage 함수 -> BP_Combo로 가져오기
BP_Combo의 Play Combo Montage 함수 화면
미리 생성한 FCombo Montage 구조체를 담고 있는 배열들을 불러와 Play Anim Montage를 호출합니다!
Sword
1. BP_Sword 수정
BP_Sword 클래스의 이벤트 그래프 화면
1. BeginPlay 이벤트
BP_Weapon의 함수 목록 중 SetCombat(공격 모드 상태) 기존의 "Set Collision Enabled" 호출과 충돌 관련 이벤트, "Component Begin Overlap"이벤트 호출을 수정합니다. 먼저, 상위 클래스 "BP_Weapon"이 제공하는 함수 "SetCombat"을 통해 Combat Type 상태를 변경합니다.
BP_Combo의 BeginPlay 이벤트 중 "Combo Table" 로딩 그리고, "BP_Combo"에서 수행하는 "Combo Table" 정보를 로딩하는 과정에서 "Sword"의 애님 몽타주들의 정보를 정상적으로 로딩하도록 Combo Table의 값을 변경합니다!
2. Begin Overlap BP_Weapon의 Send Damage 함수 화면On Component Begin Overlap(충돌) 이벤트는 간단하게 "BP_Weapon"에서 미리 구현한 Send Damage 함수를 호출하도록 합니다.