多くの場合、UI デベロッパーはバックエンド データとビジュアル デザインを複数のシステムに分割します。 こうすることで、ユーザー インターフェース (UI) の構築プロセスがより効率的になって安定します。デザイナは UI のコードを壊してしまうことなくビジュアル表現を変更でき、プログラマーは完成したフロントエンドを必要とせずに、データとシステムの作業に集中できるようになるためです。 Viewmodel プラグインは、ビューモデル アセットと View Bindings (バインディングを表示) 機能を提供することで、このワークフローの媒体として機能します。
ワークフロー
ビューモデルには UI に使用できる変数が含まれています。 デザイナは [View Binding (バインディングの表示)] パネルを使ってこれらを UI の各入力フィールドをバインドでき、プログラマーはビューモデルを自身でビルドし、必要に応じてそれをアプリケーションのコードに取り入れることができます。
ビューモデルを UMG ウィジェットに追加すると、そのウィジェットにアクセスして関数を呼び出したり、変数を更新したりできます。 ビューモデルでは、入力フィールドがビューモデルの変数にバインドされているあらゆるウィジェットにアップデートをプッシュできます。
ウィジェットが更新されるのは変数を更新したときだけであるため、これは生の属性のバインディングよりも効率の良い代替手法と考えられます。 またこの手法では、イベント駆動型の UI フレームワークを手動で設定する時間をかけずに、そのメリットを得ることができます。
必要な設定
ビューモデルをプロジェクトの UI に使用するには、[Plugins (プラグイン)] メニューで UMG Viewmodel プラグインを有効にします。
このプラグインを有効にしないと UMVVMViewModelBase クラスを使用できず、UMG で View Bindings を使用することもできません。
ビューモデル
ビューモデルの主な目的は次の 2 つです。
UI に必要な変数のマニフェストを保持する。
UI とその他のアプリケーションとの間のコミュニケーション媒体を提供する。
UI に変数を認識させる必要がある場合は、その変数をビューモデルに追加し、そのビューモデルをウィジェットに加えて、入力フィールドをその変数にバインドします。 変数を更新する必要がある場合は、そのビューモデルへの参照を取得して、そこで設定を行います。 変数によって、それらがバインドされたウィジェットに変更についての通知がなされ、更新されます。
ブループリントでビューモデルを作成する
ブループリントでビューモデルを作成するには、MVVMViewModelBase クラスを拡張します。
また、C++ でビューモデルを作成するには、INotifyFieldValueChanged インターフェースを実装します。
ブループリントのビューモデル変数
パラメータにバインドされたウィジェットに変更をブロードキャストするには、変数または関数を FieldNotifies としてマークする必要があります。 FieldNotify にするには、関数または変数の横にあるベルのアイコンをクリックします。
FieldNotify 変数を設定するすべての呼び出しは、通常の Set ノードではなく Set W/Broadcast というラベルで表示されます。
ゲームプレイ コードでこれらの変数に新しい値を設定すると、その変数にバインドされているウィジェットに、これらの変数を更新するように伝えるメッセージを送信します。
ブループリントのビューモデル関数
関数を FieldNotifies として扱うこともできます。 関数を FieldNotify として使用するには、次の条件を満たす必要があります。
Pure 関数であること。
Const とマークされていること。
1 つの値のみを返すこと。
入力変数を取らないこと。
たとえば、キャラクターの最大ヘルスに対する現在のヘルスのパーセンテージを返す Getter 関数を作成することができます。 これは、キャラクターのヘルスをパーセンタイルとして保持するために別の変数を作成したくない場合に役立つ代替手段です。
FieldNotify 関数が変更されたら、FieldNotify 変数から FieldNotify 関数をトリガーする必要があります。 詳細については、「FieldNotify 変数を使用して他の FieldNotify をトリガーする」を参照してください。
ビューモデル内の Getter および Setter ユーティリティ関数は、他の演算を実行したり、派生値を処理したりすることができます。 たとえば、プレイヤーのヘルスを追跡するビューモデルがある場合、ゲームプレイ ロジックでは float として扱っている場合でも、テキストでは整数として表示する必要がある場合があります。ProgressBar ウィジェットでこれを使用する場合はパーセンテージに変換する必要があります。
SetCurrentHealth 関数を使用すると、他の FieldNotify 変数に派生値を設定したり、ゲームが必要とする可能性のある他のロジックを実行したりすることができます。
FieldNotify 変数の値を返すためだけに Getter 関数を作成する必要はありません。これは、FieldNotify 変数の値を直接取得すれば済みます。また、後でビューモデルの変数をウィジェットにバインドしようとしたときに、追加された Getter 関数で混乱が生じる可能性があるからです。 ただし、FieldNotify Getter を使用すると、その情報を保持するために追加の変数を作成することなく、文字列などの必要な形式への変換を処理することができます。
FieldNotify 変数を使用して他の FieldNotify をトリガーする
FieldNotify 変数は、変更されると、他の FieldNotify 関数を自動的にブロードキャストすることができます。 これを設定するには、以下の手順を実行します。
[Variables (変数)] パネルで使用したい FieldNotify 変数をクリックします。
[Details (詳細)] パネルで、[FieldNotify] チェックボックスの隣にあるドロップダウンをクリックします。 他の変数および関数の FieldNotify を含む、この変数でトリガーできるすべての有効な FieldNotify が表示されます。
この変数の変更に応えて、トリガーしたい各 FieldNotify のボックスをオンにします。
これで、ターゲット変数を変更すると、ターゲット変数自体の FieldNotify 関数に加えて、その変数に関連付けられているすべての FieldNotify 関数がトリガーされます。 これにより、より多くの変数を使用する場合に比べて、派生値の処理を簡素化することができます。
C++ でビューモデルを作成する
C++ でビューモデルを作成するには、INotifyFieldValueChanged インターフェースを実装します。 また、デフォルトで実装されている UMVVMViewModelBase クラスを拡張することもできます。 ビューモデルは FieldNotify 変数に依存する UObjects であり、それらにバインドされたウィジェットに変更をブロードキャストする関数です。
ブループリントとは異なり、C++ では FieldNotify ブロードキャストを手動で呼び出す必要があります。
ビューモデル システムは、ブループリントと同じアクセス権を使用します。 ビューモデル システムでアクセスする変数と関数は、ブループリントでもアクセスできる必要があります。
FieldNotify を含む変数
ビューモデル内で変数を定義する際は、それぞれの変数に FieldNotify 指定子を含む UPROPERTY マクロを含める必要があります。 次は、FieldNotify 変数で使用される指定子の完全なリストです。
| UPROPERTY 指定子 | 説明 |
|---|---|
| プロパティをフィールド通知のブロードキャスト システムで使用できるようにします。 |
| 変数が自身の値を設定できることを示します。 ここでは Setter 関数の名前が「 |
| Setter ですが、Setter として使用するカスタム関数の名前を提供することもできます。 |
| 変数が自身の値を取得できることを示します。 ここでは Getter 関数の名前が「 |
| Getter ですが、Getter として使用するカスタム関数の名前を提供することもできます。 |
値の変更をウィジェットにブロードキャストするには FieldNotify 指定子が必要です。 この指定子を含むすべての変数が [View Binding] メニューに表示されます。 FieldNotify がない場合は、OneTime モードでのみ変数にバインドすることが可能です。
Setter と Getter のどちらの指定子を提供するかは選択することができます。 いずれも提供しない場合は、当該の演算をこのクラス外で実行できなくなります。 変数自体の通知をトリガーしたいだけの場合は、関数の名前なしに Getter か Setter 指定子を指定します。 これらは変数にアクセスすると自動的にスクリプト (ブループリント、ビューモデル、シーケンサーなど) から実行されますが、 cpp コードから自動的に呼び出されることはありません。
カスタム Getter (ゲッター) と Setter (セッター) が便利なのは次のような状況です。
変数を取得する前に演算を実行する必要がある。
変数の設定時に他の関数をトリガーするか、他の変数を更新したい。
カスタム Getter または Setter 関数を作成する際は UFUNCTIONS にしないでください。ブループリント内で Get および Set 関数が重複してリスト出力されるためです。 この変数の UPROPERTY マクロでは、変数の Get および Set の各ノードを通じてこれらへのアクセスをすでに提供しています。 また、すべてのカスタム ゲッターは const 関数にしてください。これは、唯一の役割が値を返すことのみであるためです。
C++ ではユーザーは Getter または Setter 関数の呼び出しを強制されないため、変数を保護するかプライベートにしてユーザーの間違いを防ぐ必要があります。
protected:
/**
* The variable can be accessed from the viewmodel system and can be written to. Enable TwoWay.
* FieldNotify enabled the OneWay binding mode (enable notification).
* It's protected in cpp (force the user to use the Getter/Setter).
* It's public in Blueprint
* Blueprint/ViewBindings/... will use the Getter/Setter.
*/
FieldNotify を含む関数
FieldNotifies をブロードキャストするカスタム関数を作成し、ウィジェットのプロパティを変数と同様にこれらの関数にバインドできます。 このように使用する関数は次の要件を満たしている必要があります。
FieldNotifyとBlueprintPure指定子を含むUFUNCTIONマクロが含まれる。引数を取らない。
const関数である。単一の値のみを返す (out 引数以外)。
アクセス可能である。
関数は、他の変数から派生または変換された値にバインドされるウィジェットを必要とするものの、その情報を保持する追加の変数を作成したくない場合に便利です。
たとえば、次の関数は、キャラクターの現在のヘルス値を最大ヘルス値で割ったパーセンテージ値を返す FieldNotify です。
UFUNCTION(BlueprintPure, FieldNotify)
float GetHealthPercent() const
{
//Check to avoid dividing by zero
if (MaxHealth != 0)
{
return (float) CurrentHealth / (float) MaxHealth;
}
CurrentHealth や MaxHealth が変更されたときは、GetHealthPercent の変更を手動で通知する必要があります。
マクロを使って FieldNotify をトリガーする
変数の変更時には、関数でビューモデル通知マクロの 1 つを呼び出して、バインドされているウィジェットに変更をブロードキャストする必要があります。 利用可能なマクロは次のとおりです。
| ビューモデル マクロ | 説明 |
|---|---|
UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED([メンバー名]) | イベントをブロードキャストします。 |
UE_MVVM_SET_PROPERTY_VALUE([メンバー名], [新しい値]) | フィールド値が変更されたかどうかをテストしてから、フィールドの新しい値を設定し、イベントをブロードキャストします。 |
SET_PROPERTY_VALUE マクロは BROADCAST_FIELD_VALUE マクロと同じ処理を行いますが、SET_PROPERTY_VALUE マクロでは値を割り当ててブロードキャストする前に値が変更されたかどうかを確認します。 これはビューモデル用のセッターを作成する際によく行われる確認で、利便性のために含まれています。
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))
ビューモデルをウィジェットに追加する
ビューモデルは、UMG の [Viewmodels] ウィンドウでウィジェットに追加できます。 このウィンドウにアクセスするには、UMG の [Designer (デザイナ)] タブで [Window (ウィンドウ)] > [Viewmodels (ビューモデル)] を選択します。
[+ Viewmodel (+ ビューモデル)] ボタンをクリックしてプロジェクトのビューモデルの 1 つを選び、[Select (選択)] をクリックします。
ビューモデルを初期化する
[Viewmodels] ウィンドウでビューモデルをクリックすると、[Creation Type (作成タイプ)] 設定を使ってビューモデルの初期化方法を選択できます。 選択肢は次のとおりです。
| ビューモデルの作成タイプ | 説明 |
|---|---|
Create Instance (インスタンスを作成) | ウィジェットによってビューモデルの独自のインスタンスが自動的に作成されます。 |
Manual (手動) | ウィジェットによってビューモデルとともにヌルとして初期化されます。ユーザーはインスタンスを手動で作成し、それを割り当てる必要があります。 |
Global Viewmodel Collection (グローバル ビューモデル コレクション) | プロジェクトに含まれるあらゆるウィジェットで使用できる、グローバルに利用可能なビューモデルを指します。 グローバル ビューモデル識別子が必要になります。 |
Property Paths (プロパティ パス) | 初期化時に、ビューモデルを検索するための関数を実行します。 ビューモデルの [Property Path] では、ピリオド区切りのメンバー名を使用します。 たとえば、GetPlayerController.Vehicle.ViewModel です。 プロパティ パスはウィジェットを基準とした相対パスです。 |
ビューモデルは、ウィジェットと必ずしも 1 対 1 の関係にあるわけではありません。 ビューモデルを設定してウィジェットに割り当てるにはさまざまな方法があり、1 つのビューモデルからの情報を複数のウィジェットで受け取るようにすることも可能です。 以下では、それぞれの作成タイプについて説明します。
Create Instance (インスタンスを作成)
[Create Instance] 作成メソッドでは、ウィジェットの固有のインスタンスそれぞれに対して、ビューモデルの新しいインスタンスを自動的に作成します。 これは、ビューポート内に同じウィジェットの複数のコピーがあり、その 1 つに対してビューモデルの変数を変更した場合、そのウィジェットのみが更新されて、その他すべてのコピーは変わらずに維持されることを意味します。 同じように、同じビューモデルを使用する異なるウィジェットを複数作成した場合、これらは互いの情報への変更を認識しません。 複数のウィジェットに同じデータを参照させる場合は、以下で説明する他のメソッドが便利です。 また、作成後にビューモデルを設定するオプションもあります。
C++ での初期化呼び出し後、またはブループリントでの初期化呼び出し中に、ビューモデルを割り当てることができます。 ビューモデルが設定されていない場合、システムでは新しいインスタンスのみが作成されます。 ビューモデルの作成は、PreConstruct イベントと Construct イベントの間に行われます。
Manual (手動)
[Manual] 作成メソッドでは、ユーザー自身がアプリケーションのコード内にビューモデルのインスタンスを作成し、それを手動でウィジェットに割り当てる必要があります。 ウィジェットにはビューモデルのオブジェクト参照がありますが、ユーザーがそれにビューモデルを割り当てるまでは、その値はヌルのままです。 また、Create Widget ノードでの作成時にビューモデルを割り当てることもできます。
ビューモデルを割り当てると、UI を更新したい場合に、ウィジェットへの参照を取得せずにビューモデルを更新できるようになります。 ここで、Actor クラスの同じビューモデルを UI に含まれる複数の異なるウィジェットに割り当てることができます。
Property Paths (プロパティ パス)
[Property Path] 作成メソッドでは、より明確でコード サポートの必要性が少ない代替手法を使用できます。 他のクラスでウィジェット内部にアクセスしてそのビューモデル参照を設定するのではなく、ウィジェットで一連の関数呼び出しと参照とともにアクセスしてビューモデルをフェッチします。 エディタ内の [Property Path] フィールドには、ピリオドで区切られた一連のメンバー名を入力します。また、このフィールドでは、これらの関数の呼び出しの起点として Self を想定しています。 つまり、常に編集中のウィジェットから開始されることを意味します。
[Property Path] フィールドでは Self への参照で開始することを想定しているため、手動で Self をプロパティ パスに指定しないでください。
次の例では、ウィジェットの所有するプレイヤー コントローラーをフィールドが取得し、次に現在制御しているビークルのビューモデルを取得します。
GetPlayerController.Vehicle.ViewModelブループリントで定義した関数を呼び出すこともできます。これによって、プロパティ パスのロジックを簡略化して柔軟性を高めることが可能になります。 次の例の関数は、ウィジェットを所有するキャラクターから Character Health ビューモデルを取得しています。
その後、この関数の名前をプロパティ パスとして使用できるようになります。
GetHealthViewModelGlobal Viewmodel Collection (グローバル ビューモデル コレクション)
「グローバル ビューモデル コレクション」とは、MVVM ゲーム サブシステムにおける、グローバルにアクセス可能なビューモデルのリストです。 これらは、ゲーム オプション メニューの設定など、UI 全体を通じてアクセスする必要がある可能性がある変数の処理に適しています。 ビューモデルをブループリント内でグローバル ビューモデル コレクションに追加するには、以下のステップに従います。
MVVM ゲーム サブシステムに参照を追加します。
MVVM Game Subsystem ノードのピンをドラッグし、Get Global Viewmodel Collection を呼び出します。
Global Viewmodel Collection のピンをドラッグし、Add Viewmodel Instance を呼び出します。
これらのステップを終えると、ビューモデルのインスタンスを構築し、このノードを使ってそれをコレクションに加えることができます。 これらの初期化には Game Instance クラスが便利です。
初期化モードとして [Global Viewmodel Collection] を選択した場合は、Add Viewmodel Instance ノードからの Context Name をグローバル ビューモデル識別子に提供します。 この名前はビューモデルのクラス名と一致する必要があります。 たとえば、ビューモデルの名前が「VM_GraphicsOptions」である場合は、その名前をコンテキスト名 (Context Name) とグローバル ビューモデル識別子の両方として提供します。
ビューモデルのメンバーにアクセスする
ビューモデルをウィジェットに割り当てると、ウィジェットのプロパティとしてそのビューモデルにブループリント内でアクセスできるようになり、 ビューモデルが [Variables (変数)] > [Viewmodel] カテゴリに表示されます。 ビューモデルへの参照を取得すると、その変数と関数にアクセスできるようになります。
ビューモデルで設定されるオプションによっては、内部の関数とセッターのすべてにはアクセスできない場合があります。
配列で作業する
通常、ビューモデルで配列にアクセスすることはできません。 ビューモデルで配列にアクセスするには、ビューモデル自体から配列にメンバーを直接追加、削除、取得するための独自の FieldNotify 関数を作成してください。
配列はビュー (ListView、TreeView、TileView) で使用することができます。 配列内で要素が追加、削除、移動された場合は通知する必要があります。
View Bindings (バインディングを表示)
ビューモデルを作成したら、UMG エディタでそれをウィジェットに追加して [View Bindings] ウィンドウでターゲティングできます。
View Binding をウィジェットに追加する
View Binding をウィジェットに追加するには、[Details] パネルにあるプロパティ バインディングのドロップダウンを使って追加する方法と、[View Binding] メニューを使ってすべてのウィジェットのバインディングを管理する方法の 2 つがあります。
ドラッグ&ドロップを使用する
[Viewmodels (ビューモデル)] ウィンドウで、ウィジェットにバインドしたい変数または関数をクリックし、バインドしたいフィールドの [Bind (バインド)] ドロップダウンにドラッグします。 これは、View Binding を最も簡単で迅速に作成できる方法です。
[Details] パネルを使用する
[Details] パネルで View Bindings を使用するには、バインディングを追加する先のウィジェットを選択し、バインドするプロパティの [Bind] ドロップダウンをクリックします。 ドロップダウンの下部に、そのプロパティに有効なすべてのビューモデル変数と関数が表示されます。 そのうちの 1 つをクリックしてバインディングを割り当てます。
混乱を避けるために、従来のバインディング システムを無効にします。 これを行うには、[Project Settings (プロジェクト設定)] > [Editor (エディタ)] > [Widget Designer (Team) (ウィジェット デザイナー (チーム))] の順に選択し、[Property Binding Rule (プロパティ バインディング ルール)] を [Prevent (防止)] に設定します。 これにより、従来のプロパティをウィジェットのパラメータにバインドするオプションが削除されます。
また、[Plugins] > [Model View Viewmodel (モデルビューのビューモデル)] セクションで [Allow Binding from Detail View (詳細ビューからのバインディングを許可)] を無効にすることで、ビューモデルの [Details] パネルのバインディングも無効にすることができます。 [View Binding] メニューを使用すると、引き続きビューモデルの変数をバインドすることができます。
[View Binding] メニューを使用する
[View Bindings] ウィンドウでは、View Binding の動作をより細かく制御できます。 UMG の [Designer] タブで [Window] > [View Binding] をクリックして [View Binding] ウィンドウを開きます。
[+ Add Widget (+ ウィジェットを追加)] をクリックして、[View Binding] のリストにエントリを追加します。
[Viewmodels] ウィンドウに追加したすべてのビューモデルをバインディングに使用できます。
Unreal Engine の現在のバージョンでは、[View Bindings] メニューを使ってビューモデルをバインドし、[Details] パネルでそれを再度割り当てると、そのバインディングが無効になることがあります。 これを修正するには、当該のバインディングを [View Bindings] メニューから削除して、再び割り当ててください。
View Binding を設定する
View Bindings には次の情報が含まれています。
バインディングのターゲット ウィジェットとターゲット ビューモデル。
バインドするウィジェット プロパティとビューモデル プロパティ。
バインディングの方向。2 つのターゲット プロパティ間での情報の流れを定義します。
バインディングの更新タイプ。
有効 / 無効のトグル。無効にすると、ランタイムからバインディングが削除されます。 これはバインディングがコンパイルされず、ランタイム時に利用できないことを意味します。
以下のセクションでは、それぞれのフィールドの詳細と設定方法について説明します。
ターゲット ウィジェットを選択する
View Binding エントリの最初のドロップダウンでは、View Binding を追加する先のウィジェットを選択します。 ウィジェットをクリックすると、ドロップダウンにウィジェットの階層が表示され、その親ウィジェット自体か、いずれかの子ウィジェットを選択できます。 [Select] をクリックして選択内容を確定します。
View Binding エントリを作成する
ターゲット ウィジェットの下には、ビューモデルのバインディングの設定先となる個別のプロパティのエントリがあります。 各バインディングは、それぞれが属するウィジェットと並んでいます。 1 つのウィジェットに複数のバインディングを追加するには、ウィジェットのドロップダウンの隣にある [+] ボタンをクリックします。 それぞれのバインディングは異なるプロパティをターゲットにする必要があります。
ウィジェット プロパティを選択する
View Binding エントリの最初のドロップダウンには、ターゲット ウィジェットの変数と関数がリスト表示されます。 たとえば、Progress Bar (進捗バー) ウィジェットを使用する場合は、Percent プロパティを使用できます。
C++ で定義されたプロパティまたは関数をこのリストに表示するには、UFUNCTION または UPROPERTY マクロを使ってそれを Unreal Engine のリフレクション システムに認識させる必要があります。 ブループリントで定義された変数と関数は自動的に利用可能になります。
ビューモデルのプロパティを選択する
3 つ目のドロップダウンでは、ターゲットにするビューモデルと、View Binding に使用するそのプロパティの両方を選択します。 ドロップダウンをクリックすると、このウィジェットに追加したビューモデルのリストが表示されます。
View Bindings で利用可能な変数と関数のリストを表示するために使用するビューモデルをクリックします。 これは One Way To Widget であるため、変数と関数をここに表示するには、それらに FieldNotify 指定子が含まれている必要があります。
バインド方向を設定する
2 つ目のドロップダウンでは、View Binding のバインド方向を選択します。 これにより、ウィジェットとビューモデル間の情報の流れが定義されます。
利用可能なバインド方向は次のとおりです。
| バインド方向 | 説明 |
|---|---|
One Time to Widget (ウィジェットに一度) | バインディングは、ビューモデルからウィジェットへ一度のみ適用されます。 選択したウィジェット プロパティが更新されます。 |
One Way to Widget (ウィジェットに一方向) | バインディングは、ビューモデルからウィジェットへの一方向にのみ適用されます。 ビューモデル内の対応する変数が更新されると、変数が変更されたことをウィジェットに通知し、選択したウィジェット プロパティを更新します。 関数を選択していた場合は、その関数を呼び出すことで、選択したウィジェット プロパティを更新します。 |
One Way to Viewmodel (ビューモデルに一方向) | バインディングは、ウィジェットからビューモデルへの一方向にのみ適用されます。 ウィジェットの選択したプロパティがユーザーまたはコードのいずれかによって変更された場合に、その変更をビューモデル プロパティに適用します。 典型的な例としては、ユーザー編集のテキスト フィールドやグラフィック オプションがあります。 |
Two Way (双方向) | バインディングが双方向に適用されます。 |
すべてのバインディングは、PreConstruct イベントと Construct イベントの間に 1 回実行されます。 バインド方向が TwoWay の場合、OneWay バインディングのみが実行されます。 ビューモデルの値が SetViewmodel で変更されると、そのビューモデルを含むすべてのバインディングが実行されます。
変換関数を使用する
変数に直接バインドする方法の代替手段として、変換関数を使う方法があります。 この関数では、整数値をテキストに変えるなど、ビューモデルからの変数を異なるデータ型に変換できるインターフェースが提供されます。 変換関数は、ビューモデル プロパティのドロップダウンの、ビューモデルのリストの下に表示されます。
変換関数を選択すると、その関数の引数を設定するための一連のオプションが、View Binding のドロップダウンの下に表示されます。
これらのプロパティの 1 つで [link (リンク)] ボタンをクリックすると、そのプロパティをビューモデルの値にバインドできます。
新しい変換関数はグローバルに追加することも、UserWidget (ウィジェット ブループリント) に追加することもできます。 この関数をイベント、ネットワーク、非推奨、エディタ専用にすることはできません。 関数はブループリントに表示され、1 つの入力引数と 1 つの戻り値を含める必要があります。 また、グローバルに定義されている場合は関数も静的である必要があり、 UserWidget に定義されている場合は pure で const である必要があります。
ビューモデルの作成に関するベスト プラクティス
ビューモデルを作成する際は、巨大なものにするのではなく、小さく簡潔なビューモデルにするよう心がけてください。 こうすることで、UI のデバッグが容易になります。
たとえば、RPG のキャラクターを表現するビューモデルを作成する際に、特性やインベントリ、ヒット ポイントなどの完全な配列を含めることはできますが、 ただし、このビューモデルに依存する UI 要素のいずれかをデバッグするときに、ビューモデルのデータを埋めるために、最初にキャラクター全体をスポーンする必要があります。 これを異なるコンポーネントに分割した場合は、デバッグ時にビューモデルにテスト データを提供する作業が容易になります。
ネスティングされているビューモデル
ビューモデルを別のビューモデル内にネスティングすることで、一連の複雑なデータをより柔軟に扱うことができます。
たとえば、キャラクターのヘルス値用にビューモデルを作成し、その属性 (体力、器用さ、魔法) 用に別のビューモデルを作成して、これら両方を完全なキャラクターを表現するビューモデルにネスティングできます。 テスティングの目的で、関連するビューモデルからデータを個別のウィジェットで受け取る (ヘルス値バーがキャラクターのヘルス値を参照できるなど) ことができる一方で、最終的な製品ではネスティングされているビューモデルの完全なセットを使用できます。