👣 BackStep
플레이어의 상태가 BackStep 상태가 되면 뒷걸음질치는 BackStep 기능을 구현해보았다.
스페이스바를 누르면 OnAvoid 함수가 실행되도록 함수를 등록하였다.
OnAvoid 함수에서는 플레이어의 상태가 Idle 상태인지, CanMove 상태인지를 검사한 뒤, InputComponent를 통해 MoveForward의 AxisValue가 0보다 큰지를 검사한다.
뒷걸음질 치는것은 MoveForward의 AxisValue가 음수(-1)로 나오기 때문에 양수인 경우에는 함수를 중단시킨다.
💡 InputComponent의 사용
SetupPlayerInputComponent 함수가 아닌데도 InputComponent 객체를 사용할 수 있는 이유는, SetupPlayerInputComponent 함수의 정의를 살펴보면 이해할 수 있다.
SetupPlayerInputComponent 함수에서는 InputComponent가 nullptr이라면 새로운 InputComponent를 생성하여 초기화한다. 즉, 이 말은 Player의 CreatePlayerInputComponent 함수로 생성하는 InputComponent 객체와 CPlayer가 단순히 가지고있는 InputComponent가 동일한 객체라는 의미이다.
따라서 SetupPlayerInputComponent 함수가 아니라도, Pawn을 상속받은 클래스에서는 InputComponent 라는 이름으로 객체의 함수들을 사용할 수 있다.
모든 조건에 충족한다면 StateComponent의 SetBackStepMode 함수를 호출하여 플레이어의 State값을 BackStep으로 변경한다.
State값이 바뀌면 델리게이트에 State값이 바뀔때마다 호출되는 OnStateTypeChanged 함수가 실행된다.
OnStateTypeChanged 함수를 CPlayer 클래스에서 정의하여 델리게이트에 AddDynamic으로 등록해두었다.
Player의 BackStep 함수에서는 Movement의 ControlRotation 값을 변경하고, 뒷걸음질치는 몽타주를 실행시킨다.
📚 Notify_EndState
State에 따른 몽타주를 실행시키고 난 뒤, 몽타주가 끝났을 때 다시 원상태로 State를 돌려놔야 한다.
따라서 몽타주의 끝부분에 추가할 수 있는 EndState Notify를 생성하였고, 모든 상태에 대해 사용할 수 있도록 구현하였다.
UAnimNotify를 상속받는 AnimNotify_EndState 클래스를 생성하였고, StateComponent 헤더파일을 추가하여 EStateType을 사용할 수 있도록 하였다.
이때, 상태의 끝을 알리는 기능은 플레이어만 사용하는것이 아니라 적(Enemy)도 사용할 수 있다.
그러나, 두 객체의 부모는 Character뿐이기 때문에, 부모클래스에서는 End Notify를 호출할 방법이 따로 존재하지 않는다. (엔진의 Character 클래스를 수정할 순 없기 때문)
이런 경우 유용하게 사용할 수 있는 개념이 바로 "인터페이스" 이다.
인터페이스에 관한 설명은 게시글에 따로 정리해두었다.
2023.04.11 - [Unreal4/C++] - [C++] 인터페이스(Interface), 추상클래스(Abstract), 추상함수/가상함수(Virtual)
💻 인터페이스 생성
플레이어나 Enemy의 공통된 기능을 구현하기 위해 ICharacter 라는 클래스명으로 인터페이스 클래스를 생성하였다.
인터페이스를 생성하면 클래스가 두 개 생성되는데, UInterface를 상속받는 UICharacter 클래스는 직렬화를 위한 클래스이므로 추가적인 코드를 작성하지 않는다.
그런 의미로 UINTERFACE의 속성인 MinimalAPI는 최소한의 코드만 작성하겠다는 의미이다.
기능 구현은 IICharacter 클래스에서 작성한다.
BackStep 몽타주가 끝날 때 호출될 End_BackStep 함수를 선언해두었다.
💻 인터페이스 적용
CPlayer 클래스에 인터페이스를 사용하기 위해 다중상속을 이용해 IICharacter를 상속받았고, End_BackStep 함수를 재정의하였다.
함수 내용으로는 플레이어의 Movement 설정과 State값을 Idle 로 변경하도록 작성하였다.
이러한 End_BackStep 함수의 호출은 몽타주의 끝부분에서 호출되어야 하므로, 아까 만들어두었던 Notify의 내용에 작성하였다.
IICharacter인 인터페이스 클래스를 GetOwner에 Casting하여 인터페이스를 상속받은 클래스인지 확인한 뒤, 인터페이스의 함수인 End_BackStep을 호출하였다.
컴파일 후 BackStep 애니메이션의 몽타주에 EndState 노티파이를 추가한 뒤, State Type을 BackStep으로 설정하였다.
프로그램 실행 결과, BackStep이 정상작동하는것을 확인할 수 있었다.