October 3, 2018

Rich Text Block を使ったテキストの高度なスタイル設定

作成 Cody Albert

ゲームの UI に取り組むとき、UMG の一般的なテキスト ブロックには、さまざまなスタイルのオプションやカスタマイズが用意されています。しかし、多くのデベロッパーは、スタイルの変更、インライン イメージ、ハイパーリンクなどのマークアップをサポートする、より柔軟なテキストが必要であると感じています。その多くが、試験的に採用された Rich Text Block ウィジェットにより、コードを通じて可能になっています。

4.20 リリースでは、このウィジェットが UMG で利用可能になり、その過程で、ワークフローの柔軟性、拡張性が以前と比べて向上しました。デベロッパーが必要とする可能性があるすべてのカスタマイズをサポートするのではなく、Rich Text Block が Decorator クラスに対応するようにして、デベロッパー自身がプロジェクトに必要なマークアップ機能を定義できるようにしました。独自のデコレーターを設定する例として、RichTextBlockImageDecorator.cpp に Decorator クラスが 1 つ用意されています。

この記事では、UI デザイナーとプログラマーのみなさんが UMG で新しい Rich Text Block ウィジェットを活用する方法を紹介します。また、Decorator クラスを使用して、追加機能でウィジェットを拡張する方法についても説明します。独自のカスタマイズを追加する前に、UMG に追加された Rich Text Block 機能について理解しておくと役立ちます。Rich Text Block ウィジェットを使用すると、テキスト スタイルやデコレーターを使用して、ブロックのコンテンツをカスタマイズできます。このとき、データ テーブル アセットや独自の Decorator クラスを使用できます。

データ テーブル アセットを作成したら、ユーザーが定義する任意の構造体に基づいて任意のタイプのデータを格納できます。データ テーブルを作成すると、2 つの構造体が用意されていることがわかります。Text Style RowImage Row です。Text Style Row 構造体は、Rich Text Block のビルトイン スタイルの一部であり、フォントのタイプ、たとえばアウトラインの有無、色、サイズなどを定義できます。Image Row は、RichTextBlockImageDecorator サンプル クラスに含まれ、Rich Text Block ウィジェットで任意の Decorator クラスを指定できるようにします。Text Style Row 構造体と同様に、Image Row を使用すると、インライン イメージのプロパティ、たとえばサイズのスケーリング、ティント、アライメントなどを定義できます。

RichTextBlockImageDecorator サンプル クラスは、独自のマークアップ テキストを作成するための出発点となります。そのマークアップ テキストは、イメージ、ハイパーリンク、ウィジェット全体など、任意のスレート コンテンツと置き換えることができます。データ テーブルは、任意のタイプのデータを格納でき、また Data Table アセットを通じてエディタで設定できます。

作業の開始

最初に、新しい Widget ブループリントを作成し、パレットを使用して Rich Text Block をキャンバスまでドラッグします。Rich Text Block を選択した状態で、[Details (詳細)] パネルで [Text Style Set (テキスト スタイル セット)] を見つけます。このアセット割り当てスロットにより、テキスト スタイルと、追加で使用したい任意のスタイルを定義する、スタイルのデータ テーブルを渡すことができます。新しいデータ テーブルの作成に進むには、この割り当てドロップダウンから [Data Table (データ テーブル)] を選択するか、コンテンツ ブラウザを使用して [Add New (新規追加)] - [Miscellaneous (その他)] - [Data Table (データ テーブル)] の順に選択します。
Rich-Text-Block_1.png

データ テーブルの作成は、UMG の [Details (詳細)] パネル内で行うことができます。[Pick Structure (構造体の選択)] ウィンドウのドロップダウンで、行の構造体として [Rich Text Style Row (リッチ テキスト スタイル行)] を選択します。
Rich-Text-Block_2.png

UMG の [Details (詳細)] パネルで新しいデータ テーブルをダブルクリックするか、コンテンツ ブラウザから新しいデータ テーブルを開きます。まず、データ テーブル エディタで「Default」という新しい行を作成します。この行は、テキストのデフォルト状態を表し、Rich Text Block でテキストに明示的に別のスタイルが設定されていない場合に自動的に使用されます。
Rich-Text-Block_3.png

新規に作成した Default 行の下にあるオプションを確認し、フォント、サイズ、書体などについて、ベースラインとなるスタイルを設定します。設定を完了したら、スタイルを追加していきます。[+] (プラス) ボタンをクリックして新しい行を追加し、[Row Name (行名)] テキスト ボックスに名前を入力します。

データ テーブル アセットが割り当てられた Widget ブループリントに戻り、[Details (詳細)] パネルで Rich Text Block の [Text (テキスト)] セクションにテキストを追加します。
Rich-Text-Block_4.png

場合によっては、Rich Text Block ウィジェットにテキストを表示するために、UMG のツールバーで [Compile (コンパイル)] ボタンをクリックする必要があります。
Rich-Text-Block_5.png

ここに示すテキストは、設定した Default 行を使用しています。データ テーブル アセットで作成した別のスタイルを適用するには、テキストを次のように囲みます。
Text
Rich-Text-Block_6.png

この例では、データ テーブル アセットにある行「RichText.Emphasis」をタグとして、スタイルを継承するテキスト「rich」を囲んでいます。こうすることで、設定したプロパティをテキストが継承し、黒で縁取られたオレンジ色の文字になります。

このスタイル タグは RichText.* などの接頭辞や接尾辞がなくても機能します。また、大文字と小文字は区別されません。

デコレーターの使用

この時点で、Rich Text Block 内のテキストにさまざまなスタイルを適用できるようになりましたが、テキスト以外のものを挿入する場合はどうすればいいでしょうか。この場合、デコレーターを使用して、独自のマークアップ タグを設定できます。こうしたマークアップ タグにより、スレートを使用して、テキスト内で何でもシームレスにレンダリングできます。

サンプルの RichTextBlockImageDecorator クラスを用意したので、Decorator クラスを使用して Rich Text Block にイメージを追加できます。Rich Text Style Row のビルトイン スタイルと同様に、Rich Image Row 構造体では、インライン テキストでサポートしたいすべてのイメージを定義します。
Rich-Text-Block_7.png

続いて、RichTextBlockImageDecorator クラスを継承し、作成した Rich Image Row データ テーブルをサブクラスで指定できるようにします。最も簡単な方法は、新しい Blueprint クラスを作成し、RichTextBlockImageDecorator クラスを親クラスとして選択し、ブループリントを開き、クラスの Image Set プロパティにデータ テーブルを割り当てる方法です。

注意点として、4.20 ではイメージ デコレーターが親クラスのリストに表示されませんが、これは 4.21 ではサポートされる予定です。その間は、C++ クラスとして継承し、C++ ファイル内でデータ テーブルを割り当てるか、UCLASS マクロのヘッダーの先頭に「Blueprintable」を追加することで、サブクラスをブループリントとして継承できます。

デコレーターの設定が完了したら、Rich Text Block の [Decorator Classes (デコレーター クラス)] のアレイに追加し、次のマークアップを使用して、テーブルからイメージを挿入します。

場合によっては、変更点を反映、表示するために、[Compile (コンパイル)] ボタンをクリックする必要があります。
Rich-Text-Block_8.png

新しいデコレーターの追加

RichTextBlockImageDecorator クラスをサンプルとして用意していますが、Rich Text Block の最大のメリットは、スレートを最大限に活用できるカスタム デコレーターを定義できる点です。テキストに応じて何でも追加できます。そのためには、URichTextBlockDecoratorFRichTextDecorator の 2 つのクラスを記述する必要があります。これらのクラスを設定したら、UMG で Rich Text Block ウィジェットの DecoratorClasses アレイを通じて、任意の Rich Text Block にデコレーターを追加できるようになります。また、マークアップを使用して、デコレーターでテキストをパースすることもできます。

URichTextBlockDecorator では、エディタの [Details (詳細)] パネルにプロパティを公開できる UObject クラスを定義します。少なくとも、最も手間がかかる処理を行うために作成する FRichTextDecorator インスタンスに SharedPtr を返す CreateDecorator は実装する必要があります。ここで、プロパティやユーティリティ関数を自由に実装することも可能です。そうすると、デザイナーはデコレーターのサブクラスをブループリントとして作成し、必要なデータを渡すことができます。前述のように、RichTextBlockImageDecorator には、イメージのテーブルを渡せるように、データ テーブル プロパティが定義されています。ブループリントで変更するものはすべて UObject に存在する必要があります。

FRichTextDecorator は、マークアップ タグを実際にパースして置き換えます。2 つの関数を実装する必要があります。最初の関数 Supports は、FTextRunParseResults を通じてマークアップ タグの内容を渡され、デコレーターがそのタグの処理を担当するかどうかに応じて、true または false を返します。Supports は、DecoratorClasses アレイ内のデコレーターごとに呼び出され、処理を担当するデコレーターが見つからなかった場合はフォールバックしてタグを通常のテキストとして表示します。2 つ目の関数 CreateDecoratorWidget は、サポート対象のマークアップ タグを置き換えて、ウィジェットを組み立て、返すために呼び出します。タグにテキストやメタデータが必要な場合は、FTextRunInfo にアクセスできます。

RichTextBlockImageDecorator クラスでは、SRichInlineImage ウィジェットを定義し、データ テーブルから適切なイメージを指定しています。これは、UObject ラッパー クラスに渡されてから、CreateDecoratorWidget の戻り値として渡されます。

プロジェクトでのリッチ テキストの使用

Rich Text Block のビルトイン機能を使用する方法と、Decorator クラスを記述して独自の機能を追加する方法について説明しました。それでは、実際のプロジェクトのワークフローにどのように組み込めばいいのでしょうか。

Rich Text Block を作成するたびに Decorator Classes アレイに同じデコレーターを設定している場合は、Rich Text ウィジェットの独自のサブクラスを定義し、特定のデコレーターのセットを含むようにするといいでしょう。さらにコントロールが必要な場合は、SRich Text Block ブロックはカスタムのパーサーやマーシャリングをサポートしています。独自のパーサーを記述することで、マークアップ タグが検出、処理される方法に関するルールを変更できます。カスタムのマーシャリングを行うと、ウィジェット内でテキストのレイアウトをコントロールできます。

すべてのプロジェクトのテキスト エリアに Rich Text Block ウィジェットを使用したくなるかもしれませんが、タグを探してテキストをパースする処理はパフォーマンスに影響します。パフォーマンスが懸念になる可能性があり、Rich Text Block の追加機能が必要でなければ、通常のテキスト ブロックを引き続き使用することを推奨します。

Rich Text Block ウィジェットにより、プロジェクトのテキストに面白いエフェクトを適用できる可能性が大きく広がります。このウィジェットを使用すると、テキストのハイライトやゲームパッド ボタンなどのシンプルなエフェクトから、インライン ボタンや戦利品へのリンクなどのインタラクティブなエフェクトまで適用できます。また、デコレーターを使用すれば、思いつくかぎりのものを追加できます。

Rich Text Block のドキュメントを参考にして、さっそく使い始めましょう!