🎮Unreal4/C++_Plugin

[UE4] ToolBar 버튼-1 : Command (TCommands, RegisterCommands, FExtender, AddToolBarExtension)

공대 컴린이 2023. 3. 25. 15:20
728x90

📱 ToolBar

언리얼 엔진의 상단부분을 보면 툴바(ToolBar)가 존재한다.

이러한 ToolBar에 Load Mesh 기능이나 Open Viewer 기능 등을 수행할 수 있는 커스텀 툴바 버튼을 제작해보았다.

💻 Button Command 클래스

먼저, 버튼을 관할하는 ButtonCommand 클래스를 작성하였다.

 

ButtonCommand 클래스는 버튼의 모양을 정의하는 것이 아니라 버튼의 명령을 정의하는 클래스이다.

 

#include "Framework/Commands/Commands.h" 헤더파일을 추가하여 명령들을 다룰 수 있도록 TCommands를 상속받았다.

TCommands템플릿 클래스인데 싱글톤 객체이므로 자식의 자료형인 FButtonCommand를 템플릿으로 전달하여 사용한다.

 

또한 부모 클래스인 TCommands의 순수 가상함수가 존재하기 때문에 RegisterCommands를 재정의해주었다.

 

멤버변수로는 Command에 들어갈 Command List가 필요하므로 FUICommandList를 스마트 포인터 형태로 저장하였고,

Command 명령의 수행 정보를 저장할 FUICommandInfo 변수 ID를 저장하였다.

 

ButtonCommand 클래스의 생성자에서 부모 클래스인 TCommands의 생성자를 선언하여 먼저 초기화해주었다.

TCommands의 Default 생성자가 존재하지 않으므로 Default 내용들을 입력하여 초기화하였다.

 

FEditorStyle은 에디터의 모양들을 정의할 수 있는 클래스인데 Default로는 현재 스타일을 사용하기 위해 GetStyleSetName() 함수를 사용하였다.

 

순수가상함수인 RegisterCommandsCommand 명령을 등록하는 함수로, #define LOCTEXT_NAMESPACE "" 와 #undef LOCTEXT_NAMESPACE 를 이용하여 정의해야 한다.

 🚩 #define LOCTEXT_NAMESPACE " " (" " 에는 국가명, 생략가능)

 #define LOCTEXT_NAMESPACE "" 에서는 명령을 등록해주었다.

UI_COMMAND 함수를 통해 FUICommandInfo 객체 ID 등록해주었고, 언리얼에서 Command를 식별할 명령의 이름으로 "LoadMesh"를 전달하였다.

그다음 매개변수 ""명령의 설명이고, 어떤식으로 명령을 사용할것인지 결정하는 EUserInterfaceActionType 열거형Button값을 전달하여 단순 클릭 이벤트를 수행하도록 설정하였다.

 

EUserInterfaceActionType의 Check는 클릭과 해제 이벤트를 구현하고, CollapsedButton 은 접기 기능을 구현한다. 나머지 RadioButtonToggleButton은 알고있는 그 내용이다.

 

마지막 매개변수인 Chord는 단축키를 의미하는데, 단축키를 따로 지정하지 않기 때문에 FInputChord()로 기본 초기화 내용만 전달하였다.

🚩  #undef LOCTEXT_NAMESPACE

 #undef LOCTEXT_NAMESPACE 에서는 이제 명령이 들어왔을 때 어떤 내용을 수행할것인지 수행 기능을 작성해주었다.

MapAction 함수를 통해 FuiCommandInfo 객체에 델리게이트 함수를 등록할 수 있다.

FExecuteAction 클래스의 CreateRaw 함수로 따로 델리게이트 객체를 생성하지 않고 바로 초기화해주었다.

매개변수로는 델리게이트 함수FCanExecuteAction() 구조체를 넘겨 실행할 수 있는 함수임을 전달하였다.

 

델리게이트의 실행 내용으로는 버튼이 눌렸을 때 OnClicked_ID 함수를 실행시키도록 설정하였다.

 

우선은 툴바의 버튼 Command 기능을 만들어보는 첫 단계이므로 Test 로그를 띄우도록 기능만 확인하였다.

💻 FExtender 객체 사용 및 Module에 Button Command 추가

ButtonCommand 클래스를 전부 작성하였으니 이제 Start Module에서 만든 버튼을 추가해야 한다.

 

FExtender 객체를 이용하면 ToolBar를 확장하여 커스텀 버튼을 추가할 수 있다.

 

ExampleModule.cpp - StartupModule

StartupModule 함수에서 FButtonCommand 클래스를 등록(Register)한 뒤,

Extender 객체의 AddToolBarExtension 함수를 통해 버튼을 추가하였고, ToolBar의 이벤트를 호출하여 사용할 수 있는 FToolBarExtensionDelegate를 선언하여 AddToolBar 함수도 등록하였다.

 

(Extender의 다양한 기능 중 Menu와 MenuBar가 있는데, Menu는 에디터의 왼쪽 상단에 있는 파일/편집/창/도움말들을 의미하고, MenuBar는 Menu의 기능들(도움말-문서, 뷰포트 조작법, 튜토리얼 등)을 의미하는 것이다)

 

 AddToolBarExtension 함수의 첫번째 매개변수는 UI Extension의 ID를 전달해야 하는데 에디터 개인설정 - 기타 - UI 익스텐션 포인트 디스플레이를 활성화하면 UI Extension들의 ID를 확인할 수 있다.

 

나는 커스텀 버튼Compile 영역에 추가할 것이고, 두번째 매개변수로 EExtensionHook의 Before을 전달하여 Compile 영역 이전에 추가하도록 하였다.

다음으로는 CommandList를 전달하고 마지막으로 툴바 델리게이트를 전달하였다.

 

마지막으로는 ToolBar 영역과 뷰포트 자체를 출력하는 모듈인 FLevelEditorModule을 불러와서 GetToolBarExtensibilityManagerAddExtender 함수를 호출하여 툴바 버튼을 추가한 Extender를 전달하였다.

 

ToolBar의 델리게이트에 등록한 AddToolBar 함수에서는 툴바를 다룰 수 있는 ToolBarBuilder를 매개변수로 전달받고, 단순 버튼 추가이므로 AddToolBarButton 함수를 호출하였다.

 

툴바의 추가가 끝났으니 프로그램을 실행시켜보면 Load Mesh라는 이름의 ToolBar 버튼이 추가된 것을 확인할 수 있었고,

버튼을 누르면 OnClicked_ID가 호출되며 Test 로그가 성공적으로 찍히는것을 확인할 수 있었다.

 

728x90