프로그래밍의 일반적인 패턴 중 하나로 캐릭터 명령과 같은 개념의 데이터 표현을 생성하여, 캐릭터 명령을 코드 내에서 전달하고 데이터로 취급할 수 있습니다. 이 미니게임에서 명령은 UI 상호작용을 통해 생성되어 수행을 위해 캐릭터에 전달되는 데이터로 취급되어야 합니다.
이 프로젝트에서 명령은 추상 클래스로 표현되며, 각각의 특정 명령은 forward_command 및 turnright_command와 같은 이 command 클래스의 서브클래스입니다. 명령에 추상 클래스를 사용하는 것은 유일하게 유효한 명령이 추상이 아닌 서브클래스임을 뜻합니다. command 클래스의 인스턴스를 직접 생성하려고 시도하는 경우, 코드 컴파일을 시도할 때 오류가 발생합니다.
캐릭터 명령이 command 클래스의 서브클래스이므로, command 클래스가 필요한 곳이라면 어디서든 사용할 수 있습니다. 예를 들면 이전 단계에서 다룬 캐릭터의 ExecuteCommand() 함수가 있습니다. ExecuteCommand()의 첫 번째 파라미터는 명령 타입이 필요하며, 이는 command 서브클래스의 인스턴스를 실행인자로 문제 없이 사용할 수 있다는 뜻입니다.
각 서브클래스는 명령 값을 출력할 때 올바른 텍스트가 연결되도록 DebugString()의 자체적인 구현을 제공하지만, 필요시 클래스에 더 많은 차이를 추가할 수 있습니다.
이러한 클래스에는 고유 지정자도 있으므로 클래스의 인스턴스를 비교할 수 있습니다. 이 지정자로 인스턴스를 비교할 수 있습니다.
클래스에는 computes 지정자도 있으므로 Commands 모듈에서 바로 모듈 범위의 인스턴스를 생성할 수 있습니다. 즉, 앞으로 명령의 Commands.Forward와 같이 각 명령을 표현하는 단일 고유 인스턴스를 생성할 수 있습니다.
이 예시는 열거형 타입 대신 명령 서브클래스의 인스턴스를 사용하므로, 더 많은 서브클래스를 생성하여 나중에 더 많은 명령을 추가할 수 있습니다. enum 타입의 경우 프로젝트의 초기 퍼블리싱 버전 이후에 열거형을 변경하거나 열거형에 더 많은 값을 추가할 수 없으므로, 프로젝트 퍼블리싱 후 데이터 변경이 예상되지 않는다면 enum 타입이 낫습니다.
명령 구현의 완성된 코드는 다음과 같습니다.
# This file contains the data representation of all the commands that the NPC can receive
# and utilities for the data to help with debugging and troubleshooting issues.
# Each type of command that the NPC can perform will be an instance of this class.
# The class has the unique specifier to make instances of the class comparable.
# The class has the computes specifier to be able to instantiate it at module-scope.
# The class has the abstract specifier so it cannot be instantiated directly, and
# requires subclasses to implement any non-initialized functions, like DebugString().
command := class<computes><unique><abstract>:
DebugString():string
다음 단계
명령을 정의하고, 원하는 수만큼 추가하는 방법을 살펴보았습니다.
다음 단계에서는 이러한 명령을 UI에서 사용하는 방법과 캐릭터 제어용 커스텀 UI를 추가하는 방법을 알아봅니다.