이전 글에서 캐릭터에 움직임을 부여하는 방법을 알아 보았다.
그러나, 게임 내에는 많은 캐릭터들이 존재할 수 있고, 한 캐릭터도 상태에 따라 여러 다른 움직임을 가질 수 있다. 예를 들어 탈것에 탑승한다던지 수영을 한다던지 하는 상황이 많다.
따라서 캐릭터 하나하나에 직접 움직임을 정의하기보다는 '움직임을 정의해놓은 클래스' 를 여럿 만들어 두고 그것을 적용하게끔 하면 보다 확장성 측면에서 우수할 것이다.
PlayerController 블루프린트를 만들어서 구현할 수 있다.
이전 글에서 Character 블루프린트에 정의했던 스페이스바 점프 기능을 삭제하고, 이를 PlayerController 블루프린터로 옮겨 보자.
스페이스바 인풋 노드는 존재하지만 Character 블루프린트와 다르게 'Jump' 노드를 찾을 수 없다.
왜냐 하면 점프 노드는 캐릭터에 존재하는 기능이기 때문에, 먼저 캐릭터에 접근해야 한다.
따라서 Get Player Character
함수를 사용한다.
이 노드는 명시된 플레이어가 사용하고 있는 캐릭터를 리턴해 준다. 현재로서는 멀티 플레이 기능이 없으므로 인덱스를 변경할 일은 없을 것이다.
이제 이 노드의 아웃풋 Character 핀에서 Jump 함수를 찾아 스페이스바 인풋 노드에 연결해 준다.
그리고 이를 적용하기 위해서는 게임 모드에서 '이 PlayerController를 사용하겠다' 고 알려주어야 하기 때문에 설정해 준다.
이제 게임을 실행해 보면 이전과 마찬가지로 점프할 수 있다.
이 작업을 객체지향적으로 말하면 '추상화' 했다고 표현한다. 많은 객체에서 공통적으로 사용되는 속성이나 기능을 일반화하여 정의한 것이다.
객체 지향 프로그래밍에서도 사용되는 용어인 캐스팅에 대해 짚고 넘어가야 할 필요가 있다.
내가 정의한 MyCharacter 클래스는 Character 클래스로부터 상속받고 있고, 그 위에는 Pawn 클래스, Actor 클래스 또한 상속받고 있다.
Actor 참조자는 Actor 클래스 뿐만 아니라 Character, MyCharacter 등의 객체까지도 참조할 수 있다. 그러나 그 하위 클래스에 정의된 데이터에 '접근' 할 수는 없다.
접근하기 위해서는 Actor 클래스를 그 하위 클래스로 캐스팅 해 주어야 한다.
이해를 돕기 위한 예시를 보자.
Character 클래스를 상속하는 MyCharacter 클래스를 만들고 이 클래스 내에 'Health' 라는 변수를 만들었다.
그러나 이전에 살펴본 'Get Player Character' 함수는 'Character' 참조자를 리턴한다.
따라서 하위 클래스인 MyCharacter 클래스에 정의된 health 변수를 사용할 수 없다.
따라서 우리는 이 캐릭터 클래스를 MyCharacter 클래스로 캐스팅 해 주어야 한다.
Cast to ~~~
함수를 통해 캐스팅 해 준다.
캐스팅 후에는 MyCharacter 인스턴스이므로 health에 접근할 수 있다.