🎮Unreal4/C++_Plugin

[UE4] Command 명령어-1 : Log 출력 (IConsoleCommand, IConsoleManager, HAL, VA_ARGS, RHI, TSharedPtr, MakeShareable)

공대 컴린이 2023. 3. 23. 19:27
728x90

⌨️ Command 명령어

게임을 플레이하고 ' ~ / ` ' 키를 누르면 cmd 명령어를 입력할 수 있는 콘솔 창이 나타난다.

 

이러한 command 명령어를 원하는 기능으로 구현해주는 명령어 추가를 구현해보았다.

⌨️ IConsoleCommand, IConsoleManager 클래스 사용

ExampleConsoleCommand.h

Command 명령어를 구현하기 위해 ExampleConsoleCommand 클래스를 생성하였다.

콘솔 커맨드 명령어 IConsoleCommand 클래스를 통해 추가할 수 있다.

💡 HAL

IConsoleCommand 클래스를 사용하기 위해선 HAL/IConsoleManager 헤더파일을 추가해야 한다.

여기서 HALHardware Abstraction Layer의 약자로 하드웨어 추상화 계층을 의미한다.

위키백과의 설명으론 컴퓨터의 물리적인 하드웨어와 컴퓨터에서 실행되는 소프트웨어 사이의 추상화 계층이라고 적혀있다.

지금 구현하는 프로그램상에서는 Console Manager가 수행될 때 하드웨어에 상관없이 작동될 수 있도록 중간에 추상화 과정이 포함되어있는 것으로 이해하였다.

 

ExampleConsoleCommand.cpp

먼저 FConsoleCommandDelegate 라고 하는 델리게이트를 이용하여 새로운 명령어를 추가하였다.

CreateRaw 함수로 ExampleConsoleCommand 클래스의 OpenWindow 함수를 등록해주었고,

OpenWindow 함수의 매개변수를 FString 자료형으로 정의하였지만 지금 구현하려는 명령어에 매개변수는 필요없으므로  FString("None Arguments")를 전달해주었다.

 

이때 FConsoleCommandDelegate의 함수 정의를 타고타고 들어가보면 FUNC_DECLARE_DELEGATE 라는 델리게이트 구현 방식이 적힌 정의까지 들어갈 수 있는데, 여기 TDelegate의 반환 타입이 __VA_ARGS__ 라고 정해져있다. 

💡 VA_ARGS

VA_ARGS는 가변 함수를 의미한다. (Printf도 VA_ARGS로 정의되어 있다.)

가변 함수를 정의할땐 VA_ 키워드를 붙여서 정의한다.

 

이후 IConsosleCommand* 변수인 OpenWindowCommand에 콘솔 명령을 등록하였다.

콘솔 명령 등록은 싱글톤 객체인 IConsoleManager RegisterConsoleCommand 함수를 이용하면 된다.

(RegisterConsoleVariable 함수를 이용하면 콘솔에서도 변수를 사용할 수 있다.) 


ExampleConsoleCommand.cpp

첫번째 매개변수로 명령어(L"TestCommand")를 전달하고 두번째 매개변수로 설명을 전달하였다. 세번째로는 어떤 명령이 연결될지 전달해야하므로 함수를 등록하였던 델리게이트를 전달하였다.

 

명령어를 생성했다면 프로그램이 끝날때 꼭 제거해야 하므로 소멸자에 UnregisterConsoleObject 함수로 명령어를 제거하였다.

 

델리게이트에 등록했던 OpenWindow 함수에는 현재 게임 모드인지 아닌지에 대한 로그를 출력하도록 하였다.

💡 RHI

FApp 이라는 자료형의 IsGame 함수를 이용하면 게임모드에 대한 bool 값을 반환받을 수 있다.

FApp 클래스에 GetGraphicRHI 라는 함수도 있는데 실제로 프로그래머가 명령을 내리는 대상은 위에서 설명했던 HAL이 아니고 RHI 이다.

RHIRender Hardware Interface의 약자로 렌더링 명령을 모두 가지고 있다.

⌨️ 제작한 Command 객체(ExampleConsoleCommand) 사용하기 

이제 명령어를 ExampleConsoleCommand 클래스에 모두 생성하였으므로 Module에서 해당 객체를 생성하고 실행시켜줘야 한다.

 

모듈 클래스인 ExampleModule 클래스의 헤더파일에서 동적으로 객체를 할당하기위해 스마트 포인터인 TSharedPtr를 이용하였다.

 

StartupModule 함수에서 해당 ConsoleCommand 객체를 초기화해주었다.

앞에서도 공부했었지만 스마트포인터인 ConsoleCommand의 동적할당은 MakeShareable 함수를 이용하여 new 키워드와 함께 사용해주었다.

 

이후 소멸자와 같은 ShutdownModule 함수에서 객체를 Reset 함수로 제거해주었다.

사실 스마트포인터이기 때문에 Reset 하지 않아도 알아서 제거되지만 확실히 정리해주는것이 좋아서 추가하였다.

 

이렇게 만들어진 명령은 인게임 모드인지 아닌지에 상관없이 실행시킬 수 있다.

 

C++ 클래스를 컴파일 한 뒤, 프로젝트를 껐다 키면 Cmd 창에서 생성해두었던 "TestCommand" 명령어가 생긴것을 확인할 수 있었다.

 

게임을 플레이하지 않은 상태에서 명령을 실행시키니 로그에 None Game이라고 올바르게 출력되었다.

 

게임을 플레이 한 상태에서 같은 TestCommand 명령어를 입력하면 로그에 Game 이라고 올바르게 출력되었고, 게임 플레이 상태에서는 명령어 오른쪽에 초기화했던 명령어 설명도 잘 출력되는것을 볼 수 있었다.


참조

https://ko.wikipedia.org/wiki/%ED%95%98%EB%93%9C%EC%9B%A8%EC%96%B4_%EC%B6%94%EC%83%81%ED%99%94

 

하드웨어 추상화 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. -->

ko.wikipedia.org

http://soen.kr/

 

SoEn:소프트웨어 공학 연구소

 

soen.kr

728x90