안녕하세요~ Halcy  입니다. 


오늘은 Detail Customization 의 마지막 튜토리얼로, 저번시간에 말씀드렸듯이 SComboBox를 이용하여 언리얼 공식문서와 비슷하게 Dynamic, Static 등을 선택 할 수 있게 만들어 보겠습니다!


일단 시작은 SComboBox가 무엇인가에 대해 알아보겠습니다 !


(사진 1-1) SComboBox


(사진 1-2) UMG ComboBox


ComboBox란 위 사진 처럼 클릭 했을 때 목록이 나오고 그 목록을 눌렀을 때 어떠한 이벤트등이 발생하는 Widget입니다.


(사진 1-3) 오늘의 목표!


오늘은 저 SComboBox를 이용하여 사진 1-3 을 Lighting 탭에 추가해 볼 것입니다.


(사진 1-4) CustomizeDetails 처음추가


일단 해당 콤보박스가 들어갈 곳의 이름을 MyCustomComboBox로 지정하였습니다. 그리고 SComboBox안에 저희는 String을 넣을 것이므로 TSharedPtr<FString>을 넣어주었습니다. 


그리고 실행을 해보면..!


(사진 1-5) 실패 1


위 사진 1-5 처럼 제공된 콘텐츠가 없다고 나올 것입니다. 실제로 저희는 FString을 넣을 것이라고만 명시한 뒤 그 string이 무엇인지에 대해서는 정하지 않았습니다.



(사진 1-6) 헤더에 Options 추가

(사진 1-7) Options 추가


SComboBox에서는 안에 들어갈 내용을 Option 이라고 합니다. 우리는 FString 을 넣을 것이기 때문에 FString의 배열을 Options라는 이름으로 하나 선언해 주었습니다. 그리고 그 내부에 Dynamic과 Static을 하나씩 넣어준뒤 SComboBox 클래스에 옵션을 설정해주는 OptionsSource 로 전달해 줍니다. 


이제 다시 컴파일을 해보면.. !


(사진 1-8) 실패 2


이번에도 역시 제공된 콘텐츠가 없다고 나오지만 눌러보면 안의 내용이 OnGenerateWidget() 핸들러를 제공해 주세요. 로 바뀌어 있을 것입니다..!


이제 OnGenerateWidget()을 해야하는 것을 알았으니 이게 무엇인지 알아보겠습니다.


(사진 1-9) OnGenrateWidget은 무엇인가 출처(언리얼 공식문서)


번역하면


"옵션을 나타내는 위젯을 생성하는데 사용하는 델리게이트" 


정도로 번역 할 수 있을 것입니다. 한마디로 우리가 SComboBox를 눌렀을 때 아래에 나올 리스트 위젯을 만들때 사용하는 델리게이트 정도로 알 수 있을 것입니다. 


이제 이것을 어떻게 사용하는 것인지 알아보겠습니다.


일단 OnGenerateWidget()이 어떠한 형태의 델리게이트인지 알아보기위하여 엔진내부를 살펴봤습니다.


(사진 1-10) FOnGenerateWidget 선언부


FOnGenerateWidget이 OnGenerateWidget의 델리게이트 이름입니다. 이것을 기반으로 찾아보니 사진 1-10와 같이 선언부가 나왔는데요. 델리게이트 선언 매크로를 기반으로 언리얼 문서에서 다시 찾아보았습니다.


(사진 1-11) 델리게이트 설명 출처(언리얼 공식문서)


사진 1-11 에서 보시는 바와 같이 저러한 형태가 될 것이고, RetValType은 사진 1-10에서 보시면 TSharedRef<SWidget>이 될것이며, Param1Type은 ArgumentType이 되는데 저희는 ArgumentType을 TSharedPtr<FString> 으로 사진 1-7에서 정했습니다. 


그러므로 바인딩 되어야 할 함수의 구조는 


TSharedRef<SWidget> FunctionName(TSharedPtr<FString>)


이 되어야 할 것입니다. 이제 이러한 함수 하나를 헤더에 선언해보겠습니다.


(사진 1-12) 함수 추가


그리고 다시 CPP에 이 함수의 몸통을 만들어 보겠습니다.


(사진 1-13) 함수 몸통 추가


저희는 FString 을 인자로 받을 것이기 때문에 FString을 보여주기 가장 쉬운 방법인 STextBlock을 이용하여 반환 할 것입니다. 또한 OnGenerateWidget에 바인딩된 함수는 이 SComboBox가 가지고 있는 Option의 갯수만큼 실행될 것이고 InOption은 실행 횟수마다의 배열인자가 들어갈 것이므로 이렇게 설정해주면 SComboBox를 클릭하였을 때, 


Dynamic

Static


순으로 배치 될 것입니다.


(사진 1-14) 함수 바인딩


함수가 완성 되었으므로 OnGenerateWidget에 이 함수를 바인딩 하겠습니다. 첫 번째 인자는 바인딩 할 함수가 위치하는 클래스이고, 저희는 같은 클래스 내에서 처리할 것이기 때문에 this를 넣어줍니다. 그 후 바인딩 할 함수를 넣어주면 되겠습니다.


이제 다시 컴파일 해보겠습니다.


(사진 1-15) 실패.... 반만 성공


확인을 해보면 역시 아직 제공된 콘텐츠가 없다고 나오지만 클릭을 했을 때는 저희가 원하던 결과가 나오는 것을 확인 할 수 있습니다..! 


자 그럼 왜 처음 켜졌을 때 값은 안나오면 다른 걸 클릭해도 변하지 않는가... 고민을 해보면... 


Slate는 처음부터 끝까지 프로그래머가 모든 것을 지정해야만 하는 특성이 있습니다. 특성이라기 보다는 원래 코딩이라는게 그런거지만 언리얼이 워낙 프로그래머에게 편하도록 구성이 되어있어 하다보면 당연한 것을 잊게 되곤 하지요.. ㅎㅎ


그럼 우리가 안한건 

1. 초기에 무슨 옵션으로 초기화 할지를 정하지 않았다... 

2. 다른 인자를 클릭 했을 때 그 값이 현재의 값이 되도록 변화시키지 않았다.. 


두 가지 정도로 생각 할 수 있을 것입니다.


(사진 1-16) 현재 옵션을 결정할 변수추가 


(사진 1-17) 초기화를 해줄 아규먼트 전달

현재 옵션을 결정할 변수를 하나 만들어줍니다. 그리고 그 변수를 Options배열의 0번째 인자로 초기화 해준뒤 InitiallySelectedItem로 전달해 줍니다.


이제 초기화까지 했으니 보이겠지..!!


(사진 1-18) 여전히 안보인다..


여전히 제공된 콘텐츠가 없다고 하네요... 왜 일까 고민을 해보면...


말이 이상하다는 것을 알 수 있습니다. 제공된 "콘텐츠" 가없다. SComboBox에서는 Option이라는 이름을 사용하는데 여기에선 Contents가 없다니 이상합니다.


네 Slate는 처음부터 끝까지 프로그래머가 지정해줘야하죠. 저희는 저 SComboBox안에 무엇을 보여줄지 정하지 않았습니다. 버튼을 눌렀을 때 생성될 위젯은 따로 만들어줬는데 그냥 메인으로 보여질 것이 무엇인지 정하지 않았죠. 그래서 엔진은 "너가 정한 SWidget 이 없어서 나는 보여줄게 없어" 라고 말하는 것입니다.


(사진 1-19) 보..보여랏..!


이제 저희는 현재 옵션을 보여줄 STextBlock을 SComboBox의 콘텐츠로 제공할 것이라는 코드를 넣었습니다.


(사진 1-20) 보.. 보인닷....!


이제 이렇게 하고 컴파일을 하면 드디어 정상적으로 보이는 것을 확인 할 수 있습니다. 


하지만 아직도 다른 인자를 클릭해도 바뀌지않죠..!


이제 마지막으로 다른인자를 클릭해서 바꾸는 것만 하면됩니다.

(사진 1-21) 완성 헤더


(사진 1-22) 완성 몸통


OnSelectionChanged 라는 델리게이트가 인자가 바뀔 때마다 실행될 델리게이트입니다. OnGenrateWidget과 마찬가지의 방법으로 따라가서 사용법을 알아내고 위와 같이 선언하였습니다.


한가지 달라진 점이 보일 것입니다. 바로 STextBlock의 .Text부분이 기존에 변수를 바로 넘기는 것에서 델리게이트 바인딩 형식으로 바뀌었다는 것을 알 수 있을 것입니다.


이것은 단순히 변수로만 넘겨주고 박아버리면 CurrentOption이 아무리 변경된다 하여도 STextBlock은 맨 처음 박아둔 초기값만 가지고 있을 것이나 이것을 델리게이트로 선언하면 CurrentOption 이 바뀔 때마다 정상적으로 값을 표시해 줄 것입니다.


이렇게 한 후 확인해보면!


드디어 모든 것이 정상적으로 작동하는 것을 확인 할 수 있을 것입니다.. !


여기까지가 제가 준비한 DetailCustomization의 마무리 입니다.


어떻게 많은 도움이 되셨는지 모르겠습니다.. ㅠㅠ


저도 아직 많이 부족하므로 설명이 미흡할 수 있습니다. 언제든지 피드백 주시면 반영 하도록 하겠습니다.


여기까지 무사히 따라오셨다면..!! 이제 나도 언리얼엔진 슬레이트 할 줄알아!! 라고 하실수 있지않을까요.. ㅎㅎ


감사합니다.


다음에는 SDockTab에 대해 가볍게 설명한 뒤 날씨 툴 만들기로 찾아오겠습니다.



+ Recent posts