본문 바로가기
둥지/Unreal

Unreal5 뷰모델 다뤄보기

by 까닭 2024. 1. 14.

1) Unreal View Model 소개

 

언리얼 엔진에서 Umg로 프로그래밍하고 스크립팅하기 | 언리얼 엔진 5.2 문서 | Epic Developer Community

UMG 위젯의 블루프린트와 코드를 처리하는 방법을 안내합니다.

dev.epicgames.com

UMG 뷰모델은 UI 개발 시 자주 일컫어지는 아키텍처 패턴들 중 MVVM 패턴을 기반으로 만들어진 기능이다.

해당 기능은 추가된 건 언리얼 5.1부터지만 C++ 개발만 가능하고 블루프린트는 아직 인터페이스가 존재하지 않았다. 그러다가 이번 언리얼 5.3 업데이트부터 블루프린트 개발까지 가능하게 되었다.

 

먼저 UMG 뷰모델을 다뤄보기 전에 MVVM 패턴이 무엇인지 간단히 살펴보자.

 

MVVM 패턴

MVVM 패턴 말고도 MVC, MVP 패턴들도 있지만 UMG 뷰모델이 MVVM 기반임으로 따로 다루지는 않는다.

MVVM은 Model - View - ViewModel의 약자이다.

  • Model: 데이터와 데이터에 관련된 로직. 쉽게 생각하면 데이터를 DB에서 가져오고 파싱, 저장하는 등의 데이터 관리자.
  • View: Model을 시각적으로 보여준다. 사실상 UI.
  • ViewModel: View를 표현하기 위해 만들어진 View를 위한 Model. View가 사용할 필드와 함수를 구현하고, VIew에게 상태 변화를 알려준다.

이렇게 하는 이유는,

UI를 빌드하는 프로세스가 변경사항으로 인한 영향을 덜 받게 됩니다. 디자이너는 UI 이면의 코드를 변경하는 일 없이 시각적 프레젠테이션을 변경할 수 있고 프로그래머는 프런트엔드가 완료되기를 기다릴 필요 없이 데이터와 시스템에 집중할 수 있기 때문입니다.

라고 한다.

 

백엔드 데이터와 시각 디자인을 별개의 시스템으로 나눠서 의존성을 낮추고 혹여 백엔드 데이터나 시작 디자인이 변경되었을 때 서로 영향을 덜 받기 위해서라고 할 수 있다. 이제 UMG 뷰모델을 다뤄보자.

 

2) Unreal View Model 기능 구현

1) View Model

실습 목적이라면 언리얼 5.3도 괜찮지만 실제 프로젝트에 사용할 계획이라면 언리얼 5.3.1 이상의 버젼으로 업데이트하는 것을 추천한다.

 

UMG 뷰모델을 블루프린트에서 사용했을 경우, FieldNotify 변수의 필수적인 기능을 사용하면 크래쉬가 발생하는 문제가 있었다고 한다. 다행히 해당 문제는 5.3.1부터 해결되었다. 우선 블루프린트부터 간단히 다뤄보며 체력 UI을 만들어보자.

 

 

먼저, 언리얼 엔진에 UMG 뷰모델 플러그인을 추가한 후 엔진을 재시작해준다.

UMG 뷰모델은 아직 베타 단계

 

 

그리고 MVVMViewModelBase 클래스 상속받아 새로운 클래스를 만든다. 이름에서 알 수 있듯이 해당 클래스가 ViewModel의 역할을 수행한다.

 

 

ViewModel 클래스 내부에는 체력에 관한 변수를 만든다. 초기값은 둘 다 100으로 둔다.

 

변수 옆 종 모양 버튼을 눌러주면 FieldNotify로 마킹이 되는데, 이를 통해 변수들이 게임 플레이 도중 새로운 값으로 변경될 때마다 바인딩되어 있는 위젯을 업데이트하라는 메세지가 전송된다. 즉, ViewModel에서 변경을 감지하여 View나 Model에게 이를 전파할 수 있다.

 

참고로, FieldNotify 변수의 값을 변경하려고 할 경우 일반적인 Set 노드가 아닌 Set W/Broadcast로 라벨이 지정되어 있다고 한다.

 

 

체력에 관한 변수를 만들었으니 다음으로 체력의 퍼센티지를 얻어오는 함수를 추가하자.

 

함수 역시 FieldNotify로 취급할 수 있으며 다음과 같은 조건을 만족해야 한다.

  • Pure 함수(클래스의 멤버나 상태를 변경하지 않기로 약속된 함수)여야 한다.
  • Const로 마킹되어 있어야 한다.
  • 하나의 값만 반환해야 한다.
  • 입력 변수가 존재하면 안된다.

Pure와 Const 속성은 체크박스로 체크하면 된다.

 

 

마지막으로, FieldNotify 변수를 통해 FieldNotify 함수를 브로드캐스트해야 한다.

방법은 간단하다. 체력 변수의 디테일 창에서 해당 변수가 변경될 때 트리거될 FieldNotify 박스를 체크해준다.

 

 

2) View

View에 해당하는 위젯 블루프린트를 하나 만든다.

 

 

그리고 ViewModel의 체력 정보를 표시할 간단한 체력바를 만들어 준다.

 

 

View Bindings와 ViewModels 창을 열어준다.

 

 

ViewModels 창에서 + 버튼을 눌러 만들어둔 ViewModel 클래스를 선택한다.

 

 

그리고 View Bindings에서 View 역할의 Widget Blueprint 속 체력 게이지 UI를 선택한다.

 

 

이제 게이지의 퍼센트를 ViewModel의 GetHealthPercent 함수에서 얻어올 수 있도록 위와 같이 지정해준다.

 

 

위 이미지의 화살표를 통해 위젯과 뷰 모델 간에 정보가 흐르는 방식을 결정할 수 있다.

위젯으로 단번
(One Time to Widget)
뷰 모델에서 위젯으로만 바인딩 한 번 적용. 뷰 모델에서 관련 변수를 업데이트할 경우 한 번만 위젯에 변수가 변경되었음을 알리고 선택된 위젯 프로퍼티를 업데이트함. 주로 초기화할 경우 사용.
위젯으로 단방향
(One Way to Widget)
뷰 모델에서 위젯으로만 바인딩 적용. 뷰 모델에서 관련 변수를 업데이트할 때마다 위젯에 변수가 변경되었음을 알리고 선택된 위젯 프로퍼티를 업데이트함. 또는 함수를 선택한 경우 해당 함수를 호출하면 선택된 위젯 프로퍼티가 업데이트됨.
뷰 모델로 단방향
(One Way to Viewmodel)
바인딩은 위젯에서 뷰 모델로만 적용. 위젯에서 사용자 또는 코드가 선택된 프로퍼티를 변경할 때마다 해당 변경사항을 뷰 모델 프로퍼티에 적용함. 일반적인 예시로는 사용자가 편집한 텍스트 필드 또는 그래픽 옵션.
양방향
(Two way)
바인딩이 두 방향 모두에 적용.

 

 

실행 결과