일반적으로 UI 개발자는 백엔드 데이터와 시각 디자인을 별개의 시스템으로 나눕니다. 이렇게 하면 UI를 빌드하는 프로세스가 변경사항으로 인한 영향을 덜 받게 됩니다. 디자이너는 UI 이면의 코드를 변경하는 일 없이 시각적 프레젠테이션을 변경할 수 있고 프로그래머는 프런트엔드가 완료되기를 기다릴 필요 없이 데이터와 시스템에 집중할 수 있기 때문입니다. 뷰모델(View Model) 플러그인은 뷰모델 에셋과 뷰 바인딩 을 도입하여 이 워크플로에 매개체를 제공합니다.
워크플로
뷰모델은 UI에서 사용할 수 있는 변수를 포함합니다. 디자이너는 뷰 바인딩(View Binding) 패널을 사용하여 UI에서 이러한 변수에 필드를 바인딩할 수 있으며, 프로그래머는 뷰모델 자체를 빌드하고 애플리케이션의 코드와 결합하여 적절한지 살펴볼 수 있습니다.
UMG 위젯에 뷰모델을 추가하면 해당 뷰모델에 액세스하여 함수를 호출하거나 변수를 업데이트할 수 있습니다. 뷰모델은 필드가 해당 변수에 바인딩된 위젯에 업데이트를 푸시할 수 있습니다.
이는 변수를 업데이트할 때 위젯만 업데이트하기 때문에 원시 어트리뷰트 바인딩보다 효과적인 대한 역할을 합니다. 또한 시간 설정을 수동으로 구현할 필요가 없으므로 이벤트 기반 UI 프레임워크의 이점을 실현할 수 있습니다.
필수 구성
프로젝트의 UI에서 뷰모델을 사용하려면 플러그인(Plugins) 메뉴에서 UMG 뷰모델(UMG Viewmodel) 플러그인을 활성화해야 합니다.
이 플러그인을 활성화하지 않으면 UMVVMViewModelBase 클래스를 사용할 수 없으며 UMG에서 뷰 바인딩을 사용할 수 없습니다.
뷰모델
뷰모델은 다음과 같은 두 가지 목적을 가집니다.
-
UI에 필요한 변수의 매니페스트를 관리합니다.
-
UI와 애플리케이션의 나머지 요소 간의 커뮤니케이션을 위한 매개체를 제공합니다.
UI가 변수를 인지해야 하는 경우, 뷰모델에 변수를 추가한 다음 뷰모델을 위젯에 추가하여 필드를 바인딩할 수 있습니다. 변수를 업데이트해야 하는 경우, 뷰모델에 대한 레퍼런스를 구하고 여기에서 바로 설정할 수 있습니다. 그런 다음 변경사항과 관련된 변수에 바인딩된 위젯을 노티파이하고 업데이트합니다.
뷰모델 생성
INotifyFieldValueChanged 인터페이스를 구현하여 C++에서 뷰모델을 생성할 수 있습니다. UMVVMViewModelBase 클래스가 이를 구현하며, 사용자는 단순히 확장하기만 하면 됩니다. 뷰모델은 FieldNotify 변수와 함수에 바인딩된 위젯에 변경사항을 브로드캐스트하는 함수를 기반으로 하는 UObjects 입니다.
앞으로 출시되는 언리얼 엔진 버전에서는 블루프린트로 뷰모델을 생성하는 것이 가능해집니다.
뷰모델 시스템은 블루프린트와 동일한 액세스 권한을 사용합니다. 뷰모델 시스템에서 변수와 함수에 액세스하려면 블루프린트에서도 액세스할 수 있어야 합니다.
FieldNotify와 변수
뷰모델에서 변수를 정의할 때는 각 변수가 FieldNotify 지정자를 갖춘 UPROPERTY 매크로가 있어야 합니다. FieldNotify 변수에 사용되는 지정자의 전체 목록은 다음과 같습니다.
| UPROPERTY 지정자 | 설명 |
|---|---|
FieldNotify |
필드 알림 브로드캐스트 시스템에서 프로퍼티를 사용할 수 있도록 합니다. |
Setter |
변수가 값 설정을 허용해야 함을 나타냅니다. Setter 함수가 Set[Variable Name] 포맷의 이름을 갖는다고 가정합니다. |
Setter="[FUNCTION_NAME]" |
Setter로 사용할 커스텀 함수의 이름을 제공할 수 있습니다. |
Getter |
변수가 값 얻기를 허용해야 함을 나타냅니다. Getter 함수가 Get[VariableName] 포맷의 이름을 갖는다고 가정합니다. |
Getter="[FUNCTION_NAME]" |
Getter로 사용할 커스텀 함수의 이름을 제공할 수 있습니다. |
FieldNotify 지정자는 위젯에 값 변경사항을 브로드캐스트해야 합니다. 이 지정자를 가진 변수는 '뷰 바인딩' 메뉴에 표시됩니다. FieldNotify 가 없는 경우 OneTime 모드에서만 변수에 바인딩할 수 있습니다.
Setter 또는 Getter 지정자를 제공할지 여부는 사용자가 결정할 수 있습니다. 두 지정자 중 하나를 제공하지 않기로 결정할 경우, 이 클래스 외부에서는 연산을 수행할 수 없습니다. 변수 자체를 위한 알림을 트리거하려는 경우에는 함수 이름 없이 Getter 및 Setter 지정자만 지정하면 됩니다. 이것은 변수에 액세스할 때 스크립트(블루프린트, 뷰모델, 시퀀서 등)에서 자동으로 실행됩니다. cpp 코드에서는 자동으로 호출되지 않습니다.
커스텀 Getter 및 Setter는 다음과 같은 경우에 유용합니다.
-
변수를 얻기 전에 연산을 수행해야 하는 경우
-
다른 함수를 트리거하려고 하거나 변수를 설정할 때 다른 변수를 업데이트하려는 경우
커스텀 Getter 또는 Setter 함수를 생성하는 경우 이러한 함수를 UFUNCTIONS 로 만들면 블루프린트에서 Get 함수와 Set 함수에 대해 상당히 많은 목록이 생성되므로 피해야 합니다. 해당 변수에 대한 UPROPERTY 매크로는 변수의 Get 노드와 Set 노드 형태로 이에 대한 액세스를 이미 제공합니다. 커스텀 Getter const 함수 또한 만들어야 하며, 해당 함수의 유일한 목적은 값을 반환하는 것입니다.
C++는 사용자가 Getter 또는 Setter 함수를 호출하도록 강제하지 않기 때문에, 사용자가 실수하는 것을 방지하려면 이 변수는 protected 또는 private이어야 합니다.
protected:
/**
* 이 변수는 뷰모델 시스템에서 액세스할 수 있으며 쓰기가 가능합니다. TwoWay를 활성화합니다.
* FieldNotify가 OneWay 바인딩 모드를 활성화 합니다(알림 활성화).
* cpp에서 protected입니다(사용자가 Getter/Setter를 사용하도록 강제함).
* 블루프린트에서 public입니다.
* Blueprint/ViewBindings/...는 Getter/Setter를 사용합니다.
*/
UPROPERTY(BlueprintReadWrite, FieldNotify, Setter, Getter)
int32 MyVariableA;
private:
/**
* 이 변수는 뷰모델 시스템에서 액세스할 수 있습니다.
* FieldNotify가 없고, OneTime 바인딩 모드만 사용할 수 있습니다.
* cpp에서 private입니다(사용자가 Getter/Setter를 사용하도록 강제함).
* `AllowPrivateAccess` 로 인해 블루프린트에서 public입니다.
* Blueprint/ViewBindings/...는 Getter/Setter를 사용합니다.
*/
UPROPERTY(BlueprintReadOnly, FieldNotify, Setter, Getter, meta=(AllowPrivateAccess))
int32 MyPropertyB;
FieldNotify와 함수
FieldNotifies 를 브로드캐스트하는 커스텀 함수를 생성할 수 있으며, 변수와 동일한 방식으로 위젯의 프로퍼티를 이러한 함수에 바인딩할 수 있습니다. 이런 방식으로 사용되는 함수는 다음의 요구 사항을 따라야 합니다.
-
FieldNotify및BlueprintPure지정자에UFUNCTION매크로가 있어야 합니다. -
실행인자를 취하지 않아야 합니다.
-
const함수여야 합니다. -
단일 값만 반환해야 합니다(out 실행인자 없음).
함수는 위젯을 다른 변수에서 파생되었거나 변환된 값에 바인딩하려고 하지만 해당 정보를 보유할 변수를 추가로 생성하는 것을 원하지 않는 경우에 유용합니다.
예를 들어 다음 함수는 캐릭터의 최대 체력으로 나눈 현재 체력의 퍼센트 값을 반환하기 위한 FieldNotify입니다.
UFUNCTION(BlueprintPure, FieldNotify)
float GetHealthPercent() const
{
//0으로 나누지 않도록 확인합니다.
if (MaxHealth != 0)
{
return (float) CurrentHealth / (float) MaxHealth;
}
else
{
return 0;
}
}
CurrentHealth 또는 MaxHealth 변경 시 GetHealthPercent 가 변경되었음을 수동으로 알려야 합니다.
매크로로 FieldNotify 트리거하기
변수를 변경할 때는 함수가 뷰모델 알림 매크로 중 하나를 호출하여 바인딩된 위젯에 변경사항을 브로드캐스트해야 합니다. 사용 가능한 매크로의 목록은 다음과 같습니다.
| 뷰모델 매크로 | 설명 |
|---|---|
| UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED([Member name]) | 이벤트를 브로드캐스트합니다. |
| UE_MVVM_SET_PROPERTY_VALUE([Member Name], [New Value]) | 필드의 값이 변경되었는지 테스트한 다음 필드의 새 값을 설정하고 이벤트를 브로드캐스트합니다. |
SET_PROPERTY_VALUE 매크로는 값을 할당하고 브로드캐스트하기 전에 값이 변경되었는지 확인한다는 점을 제외하고는 BROADCAST_FIELD_VALUE 매크로와 동일한 역할을 합니다. 이 확인 작업은 뷰모델을 위한 Setter를 생성할 때 일반적으로 수행되는 것으로, 편의를 위해 포함되어 있습니다.
값에 직접 바인딩된 위젯을 노티파이하거나 함수의 이름을 취할 수 있는 경우, BROADCAST_FIELD_VALUE_CHANGED 매크로는 변수 자체를 취할 수 있습니다.
예시
다음 코드 스니펫은 위의 개념을 사용하는 뷰모델 클래스의 예시입니다. GetHealthPercent는 Getter와 Setter에서 별도의 함수로 정의되어 있지만 변수가 변경될 때 노티파이하기 위해 Setter가 이를 호출합니다.
UCLASS(BlueprintType)
class UVMCharacterHealth : public UMVVMViewModelBase
{
GENERATED_BODY()
private:
UPROPERTY(BlueprintReadWrite, FieldNotify, Setter, Getter, meta=(AllowPrivateAccess))
int32 CurrentHealth;
UPROPERTY(BlueprintReadWrite, FieldNotify, Setter, Getter, meta=(AllowPrivateAccess))
int32 MaxHealth;
public:
void SetCurrentHealth(int32 NewCurrentHealth)
{
if (UE_MVVM_SET_PROPERTY_VALUE(CurrentHealth, nNewCurrentHealth))
{
UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED(GetHealthPercent);
}
}
void SetMaxHealth(int32 newMaxHealth)
{
if (UE_MVVM_SET_PROPERTY_VALUE(MaxHealth, NewMaxHealth))
{
UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED(GetHealthPercent);
}
}
int32 GetCurrentHealth() const
{
return CurrentHealth;
}
int32 GetMaxHealth() const
{
return MaxHealth;
}
public:
UFUNCTION(BlueprintPure, FieldNotify)
float GetHealthPercent() const
{
if (MaxHealth != 0)
{
return (float) CurrentHealth / (float) MaxHealth;
}
else
return 0;
}
};
위젯에 뷰모델 추가하기
UMG의 '뷰모델' 창에서 위젯에 뷰모델을 추가할 수 있습니다. 이 창은 'UMG 디자이너(UMG Designer)' 탭의 창(Window) > 뷰모델 에서 찾을 수 있습니다.
+ 뷰모델(+ Viewmodel) 버튼을 클릭하여 프로젝트의 뷰모델 중 하나를 선택한 다음 선택 을 클릭합니다.
뷰모델 초기화하기
'뷰모델' 창에서 뷰모델을 클릭할 때 생성 타입 세팅을 사용하여 뷰모델을 초기화하는 방법을 선택할 수 있습니다. 다음과 같은 방식을 사용할 수 있습니다.
| 뷰모델 생성 타입 | 설명 |
|---|---|
| 인스턴스 생성 | 위젯은 뷰모델의 인스턴스를 자동으로 생성합니다. |
| 수동 | 위젯은 뷰모델을 Null로 초기화하기 때문에 인스턴스를 수동으로 생성한 다음 할당해야 합니다. |
| 글로벌 뷰모델 컬렉션 | 프로젝트에서 위젯에 의해 사용될 수 있는 글로벌로 사용 가능한 뷰모델을 참고합니다. 글로벌 뷰모델 식별자 가 필요합니다. |
| 프로퍼티 경로 | 초기화 시 함수를 실행하여 뷰모델을 찾습니다. 뷰모델 프로퍼티 경로 는 마침표로 구분된 멤버 이름을 사용합니다. 예를 들면 GetPlayerController.Vehicle.ViewModel 과 같습니다. 프로퍼티 경로는 언제나 위젯에 대해 상대적입니다. |
뷰모델은 반드시 위젯과 일대일 관계를 가지는 것은 아닙니다. 뷰모델을 구성하고 위젯에 할당하는 방법에는 여러 가지가 있으며 다수의 위젯이 단일 뷰모델에서 정보를 취할 수 있습니다. 각 생성 타입 방식은 아래에 자세히 설명되어 있습니다.
인스턴스 생성
인스턴스 생성 생성 방식은 위젯의 고유한 각 인스턴스에 대해 뷰모델의 새로운 인스턴스를 자동으로 생성합니다. 즉, '뷰포트(Viewport)'에 동일한 위젯의 복제본이 여러 개 있고 그 중 하나의 뷰모델 변수를 변경하면 다른 모든 사본은 동일하게 유지되지만 해당 위젯은 업데이트됩니다. 이와 유사하게, 동일한 뷰모델을 사용하는 여러 개의 서로 다른 위젯을 생성하는 경우 이러한 위젯은 다른 위젯의 정보가 변경된 것을 인지하기 못합니다. 아래에 소개된 다른 방식은 다수의 위젯이 동일한 데이터를 레퍼런스하기를 원하는 경우 유용합니다. 또한 뷰모델을 생성한 다음 설정하는 옵션도 있습니다.
C++에서 콜백을 초기화한 다음이나 블루프린트에서 콜백을 초기화하는 동안 뷰모델을 할당할 수 있습니다. 뷰모델이 설정되어 있지 않은 경우 시스템은 새 인스턴스만 생성합니다. 뷰모델은 PreConstruct 이벤트와 Construct 이벤트 사이에서 생성됩니다.
수동
수동 생성 방식을 사용하면 애플리케이션 코드의 특정 위치에서 뷰모델의 인스턴스를 생성한 다음 이를 위젯에 직접 할당해야 합니다. 위젯은 뷰모델 오브젝트 레퍼런스를 가지지만 뷰모델을 할당할 때까지는 Null 값을 가지게 됩니다. 뷰모델을 할당하면 위젯에 대한 레퍼런스를 구하지 않고 UI를 업데이트하려고 할 때마다 업데이트할 수 있습니다.
이렇게 하면 UI에서 서로 다른 다수의 위젯에 동일한 뷰모델을 할당할 수 있게 됩니다.
프로퍼티 경로
프로퍼티 경로 생성 방식은 잠재적으로 더 명확한 대안을 제공하며 코드로 지원해야 하는 부분이 적습니다. 다른 클래스가 뷰모델 레퍼런스를 설정하기 위해 위젯 내에 접근하는 대신 위젯이 일련의 함수 호출에 접근 및 레퍼런스하여 뷰모델을 가져옵니다. 에디터의 '프로퍼티 경로(Property Path)' 필드에는 마침표로 구분된 일련의 멤버 이름을 입력할 수 있으며, 이러한 함수 호출의 시작점을 Self 라고 가정합니다. 즉, 항상 편집하고 있는 위젯에서 시작합니다.
프로퍼티 경로에서 Self 를 직접 지정하면 안됩니다. 프로퍼티 경로 필드는 Self 에 대한 레퍼런스로 시작할 것이라고 이미 예상하기 때문입니다.
예를 들어 다음 필드는 위젯의 자체 플레이어 컨트롤러를 구한 다음 현재 제어하고 있는 비히클에 어태치된 뷰모델을 구합니다.
GetPlayerController.Vehicle.ViewModel
블루프린트에서 정의한 함수를 호출할 수도 있는데, 이렇게 하면 프로퍼티 경로를 위한 로직을 간소화할 수 있기 때문에 더 높은 유연성을 확보할 수 있습니다. 예를 들어 다음 함수는 위젯을 소유하는 캐릭터에서 캐릭터 체력 뷰모델을 구합니다.
그런 다음 이 함수의 이름을 프로퍼티 경로로 사용할 수 있습니다.
GetHealthViewModel
글로벌 뷰모델 컬렉션
글로벌 뷰모델 컬렉션은 MVVM 서브시스템 에서 전역으로 액세스 가능한 뷰모델의 목록입니다. 이는 게임의 옵션 메뉴를 위한 세팅과 같이 UI를 통해 액세스해야 하는 변수를 처리하는 데 이상적입니다. 블루프린트에서 글로벌 뷰모델 컬렉션에 뷰모델을 추가하려면 다음 단계를 따르세요.
-
MVVM 서브시스템에 레퍼런스를 추가합니다.
-
'MVVMSubsystem' 노드에서 핀을 드래그한 다음 Get Global View Model Collection 을 호출합니다.
-
'Get Global View Model Collection' 노드에서 핀을 드래그한 다음 Add View Model Instance 를 호출합니다.
뷰모델의 인스턴스를 생성하고 이 노드를 사용하여 컬렉션에 추가할 수 있습니다. 게임 인스턴스 클래스를 사용하면 이를 간편하게 초기화할 수 있습니다.
글로벌 뷰모델 컬렉션을 초기화 모드로 선택하는 경우에는 글로벌 뷰모델 식별자 의 'Add View Model Instance' 노드에서 컨텍스트 이름 을 제공해야 합니다. 이 이름은 뷰모델을 위한 클래스와 일치해야 합니다. 예를 들어 뷰모델에서 'VM_GraphicsOptions'가 호출된 경우 컨텍스트 이름과 글로벌 뷰모델 식별자를 모두 제공해야 합니다.
뷰모델의 멤버에 액세스하기
위젯에 뷰모델을 할당한 후에는 블루프린트에서 위젯의 프로퍼티로 액세스할 수 있습니다. 이는 변수(Variables) > 뷰모델 카테고리에서 찾을 수 있습니다. 뷰모델에 대한 레퍼런스를 가지고 있으면 뷰모델의 변수와 함수에 액세스할 수 있습니다.
뷰모델에 환경설정된 옵션이 무엇인지에 따라 내부의 모든 함수 또는 Setter에 액세스하지 못할 수도 있습니다.
배열로 작업하기
일반적으로 배열은 뷰모델에서 액세스할 수 없습니다. 뷰모델에서 배열에 액세스하려면 뷰모델 자체에서 배열을 직접 추가하고 삭제하고 구할 수 있게 FieldNotify 함수를 생성해야 합니다.
뷰(ListView, TreeView, TileView)와 함께 배열을 사용할 수 있습니다. 엘리먼트가 배열 내에서 추가, 제거 또는 이동될 경우 노티파이해야 합니다.
뷰모델 생성 모범 사례
뷰모델을 생성할 때는 큰 모놀리식 뷰모델 대신 작고 간결한 뷰모델을 사용해야 합니다. 이렇게 하면 UI를 디버깅하기가 수월해집니다.
예를 들어 특징, 인벤토리, 히트 포인트로 구성된 완전한 배열을 사용하여 RPG에서 캐릭터를 나타내는 뷰모델을 생성할 수 있습니다. 하지만 이 뷰모델에 기반하는 UI의 일부를 디버깅하기 위해서는 먼저 전체 캐릭터를 스폰하여 뷰모델의 데이터를 채워야 합니다. 이를 서로 다른 컴포넌트로 분할하면 디버깅할 때 테스트 데이터로 더 쉽게 채워 넣을 수 있습니다.
뷰모델은 다른 뷰모델에 중첩할 수 있습니다. 이렇게 하면 복잡한 데이터 세트를 나타낼 때 유용할 수 있습니다.
뷰 바인딩
뷰모델을 생성한 후에는 UMG 에디터에서 뷰모델을 위젯에 추가하고 '뷰 바인딩' 창으로 타기팅할 수 있습니다.
위젯에 뷰 바인딩 추가하기
위젯에 뷰 바인딩을 추가하는 경우 두 가지 방법을 사용할 수 있습니다. 즉, '디테일(Details)' 패널에서 프로퍼티 바인딩 드롭다운으로 추가하거나 '뷰 바인딩' 메뉴를 사용하여 위젯의 모든 바인딩을 관리할 수 있습니다.
디테일 패널 사용하기
'디테일' 패널에서 뷰 바인딩을 사용하려면 바인딩을 추가하려는 위젯을 선택한 다음 바인딩하려는 프로퍼티에서 바인드(Bind) 드롭다운을 클릭합니다. 해당 프로퍼티에 유효한 뷰모델 변수 및 함수는 드롭다운 하단에 표시됩니다. 바인딩을 할당하려면 드롭다운 중 하나를 클릭합니다.
뷰 바인딩 메뉴 사용하기
'뷰 바인딩' 창을 사용하면 뷰 바인딩의 행동 방식을 보다 세부적으로 제어할 수 있습니다. 'UMG 디자이너' 탭에서 창 > 뷰 바인딩 을 클릭하여 '뷰 바인딩' 창을 엽니다.
+ 위젯 추가(Add Widget) 를 클릭하여 뷰 바인딩 목록에 추가합니다.
'뷰모델' 창에서 추가한 모든 뷰모델을 바인딩할 수 있습니다.
현재 버전의 언리얼 엔진에서는 '뷰 바인딩' 메뉴에서 뷰모델을 바인딩한 다음 디테일 패널을 사용하여 다시 할당할 경우 바인딩이 유효하지 않게 될 수 있습니다. 이를 해결하기 위해서는 '뷰 바인딩' 메뉴에서 바인딩을 삭제한 다음 다시 할당해야 합니다.
뷰 바인딩 환경설정하기
뷰 바인딩에는 다음과 같은 정보가 포함되어 있습니다.
- 타깃 위젯 및 바인딩을 위한 타깃 뷰모델
- 위젯 프로퍼티 및 바인딩하려는 뷰모델 프로퍼티
- 두 타깃 프로퍼티 간 정보의 흐름을 결정하는 바인딩의 방향
- 바인딩의 업데이트 타입
- 바인딩을 비활성화 시 런타임에서 제거하는 활성화/비활성화 토글입니다. 즉, 이 바인딩은 컴파일되지 않으며 런타임에서 사용할 수 없습니다.
다음 섹션에서는 이러한 필드에 대한 세부 내용과 환경설정 방법을 살펴봅니다.
타깃 위젯 선택하기
뷰 바인딩 항목의 첫 번째 드롭다운에서는 뷰 바인딩을 추가할 위젯을 선택합니다. 클릭하면 드롭다운에 위젯의 계층구조가 표시되고 부모 위젯 또는 자손 위젯을 선택할 수 있습니다. 선택 을 클릭하여 선택 사항을 확인합니다.
뷰 바인딩 항목 생성하기
타깃 위젯 아래에는 뷰모델 바인딩을 구성하려는 개별 프로퍼티의 항목이 있습니다. 각 바인딩은 속해 있는 위젯에서 들여쓰기로 표시됩니다. 위젯의 드롭다운 옆에 있는 + 버튼을 클릭하여 단일 위젯에 여러 개의 바인딩을 추가할 수 있습니다. 각 바인딩은 서로 다른 프로퍼티를 타기팅해야 합니다.
위젯 프로퍼티 선택하기
뷰 바인딩 항목의 첫 번째 드롭다운에는 타깃 위젯의 변수 및 함수의 목록이 표시됩니다. 예를 들어 진행률 표시줄 위젯 선택을 사용할 경우 퍼센트 프로퍼티를 사용할 수 있습니다.
이 목록에 표시하기 위해 C++로 정의된 프로퍼티 또는 함수의 경우 UFUNCTION 또는 UPROPERTY 매크로를 사용하여 언리얼 엔진 리플렉션 시스템에 표시할 수 있습니다. 블루프린트에서 정의한 변수 및 함수는 자동으로 사용할 수 있습니다.
뷰모델 프로퍼티 선택하기
세 번째 드롭다운에서는 타기팅할 뷰모델과 뷰 바인딩에 사용할 프로퍼티를 선택할 수 있습니다. 클릭하면 이 위젯에 추가한 뷰모델의 목록이 표시됩니다.
사용하려는 뷰모델을 클릭하면 뷰 바인딩에 사용할 수 있는 변수 및 함수의 목록이 표시됩니다. 이것은 위젯에 한 방향(One Way To Widget) 이기 때문에 변수 및 함수를 여기에 표시하려면 FieldNotify 지정자가 있어야 합니다.
바인딩 방향 설정하기
두 번째 드롭다운에서는 뷰 바인딩의 바인딩 방향 을 선택할 수 있습니다. 바인딩 방향은 위젯과 뷰모델 간 정보가 흐르는 방식을 결정합니다.
사용 가능한 바인딩 방향은 다음과 같습니다.
| 바인딩 방향 | 설명 |
|---|---|
| 위젯에 한 번(One Time to Widget) | 바인딩이 뷰모델에서 위젯에 한 번만 적용됩니다. 이로 인해 선택된 위젯 프로퍼티가 업데이트됩니다. |
| 위젯에 한 방향(One Way to Widget) | 바인딩이 뷰모델에서 위젯에만 적용됩니다. 뷰모델에서 관련 변수를 업데이트할 때마다 위젯에 변수가 변경되었음을 알리고 선택된 위젯 프로퍼티를 업데이트합니다. 또는 함수를 선택한 경우 해당 함수를 호출하면 선택된 위젯 프로퍼티가 업데이트됩니다. |
| 뷰모델로 단방향(One Way to Viewmodel) | 바인딩은 위젯에서 뷰모델로만 적용됩니다. 위젯에서 사용자 또는 코드가 선택된 프로퍼티를 변경할 때마다 해당 변경사항을 뷰모델 프로퍼티에 적용합니다. 일반적인 예시로는 사용자가 편집한 텍스트 필드 또는 그래픽 옵션이 있습니다. |
| 양방향 | 바인딩이 두 방향 모두에 적용됩니다. |
모든 뷰모델은 PreConstruct 이벤트와 Construct 이벤트 사이에서 한 번 실행됩니다. 바인딩 방향이 TwoWay인 경우 OneWay 바인딩만 실행됩니다. 뷰모델 값이 SetViewmodel을 사용하여 변경되면 해당 뷰모델을 포함하는 모든 바인딩이 실행됩니다.
변환 함수 사용하기
변수에 대한 직접 바인딩의 대안으로 변환 함수 를 선택할 수 있습니다. 변환 함수는 인티저를 텍스트로 변경하는 것과 같이 뷰모델의 변수를 다른 타입의 데이터로 변환하기 위한 인터페이스를 제공합니다. 변환 함수는 뷰모델 목록 아래의 뷰모델 프로퍼티 드롭다운에 표시됩니다.
변환 함수를 선택하면 함수의 실행인자를 환경설정할 수 있는 옵션의 목록이 뷰 바인딩의 드롭다운 아래에 표시됩니다.
이러한 프로퍼티 중 하나의 링크 버튼을 클릭하면 뷰모델 값에 해당 프로퍼티를 바인딩할 수 있습니다.
새로운 변환 함수는 글로벌 또는 UserWidget(위젯 블루프린트)에 추가될 수 있습니다. 이 함수는 이벤트, 네트워크, 지원 중단됨 또는 에디터 전용이어서는 안됩니다. 이 함수는 블루프린트에 표시되어야 하고, 하나의 입력 실행인자와 하나의 반환 값을 가져야 합니다. 글로벌로 정의되는 경우, 이 함수는 static이어야 합니다. UserWidget에서 정의되는 경우, 이 함수는 pure 및 const여야 합니다.