Unreal Engine (UE) には、グラフィックスやテキストを画面の範囲内に制限するスレートのクリップ処理システムが導入されています。作成されたオブジェクトとパネルの周囲に長方形 (またはクリップする領域) を作成します。このシステムはエディタおよび UMG UI Designer ツール全体で使用されます。ユーザーは、スレートを使って必要な時にエディタでパネルを移動し、そのサイズを変更することができます。クリップ処理システムを使うと、テキストとグラフィックスをクリップする領域に収めることができます。UMG のレンダリング トランスフォームはさらに優秀で、UI に合うようにクリップします。
新機能
Unreal Engine 4.17 では、クリップ処理システムをさらに柔軟にするために大幅な見直しを行いました。これにより、プロジェクトの UI に使用する UMG などのツール システムにレンダリング エフェクトを追加する可能性が広がりました。 これまでのバージョンで使われていたクリップ処理システムはレイアウト空間が座標軸に平行のみという制限があったため、 下図のように、エッジ周りのレンダリング トランスフォーム全般が非常に難しい作業でした。
![]() |
![]() |
この例では、ウィジェットが回転しているのにクリップする領域 (白い点) は回転していないため、キャンバス パネル境界内にあるにもかかわらずグラフィックによるレンダリングが行われていないことが分かります。
クリッピング システムのバージョン 1.0 と 2.0 の違いを比較すると、このようになります。
Clipping 1.0 (4.16 以前) | Clipping 2.0 (4.17 以降) |
---|---|
|
|
これまでは空間は座標軸に平行であることが必須でしたが、新しいシステムはウィジェットのレンダリング空間でのクリップ処理に対応しているため、 (左図のような) クリップ処理の問題に対する心配がなくなり、ウィジェットの最外部にクリップするようになりました。ウィジェットの内側でトランスフォームを適用すると、端 (右) にぴったりクリップされます。
![]() |
![]() |
---|---|
4.16 以前のクリッピングとトランスフォーム | 4.17 以降で子のトランスフォームに合わせて |
端でクリップ処理を適用した場合 |
ほとんどの場合、ウィジェットのクリップ ステートの変更を心配する必要はありません。例えばゲーム UI であれば、UMG ではウィジェット調節の必要はなく、スクロール パネル、またはエディタのようにテキストの長さを調節できないので、ウィンドウのサイズ変更のためップする必要のある場合にウィジェットを変更します。

以下は、各種クリップ処理設定の一例です。
- 左 - ボタン上またはテキスト上でのクリップ処理が有効にされていない。
- 中央 - テキスト上でクリップ処理が有効にされている。
- 右 - ボタン上でクリップ処理が有効にされている。
異なるオブジェクトにクリップ処理を割り当てた時に生じる差に注目してください。境界線までクリップするため、パディングのようなものはここでは考慮されません。従って、ボタンにクリップ処理を設定すると、文字が端までずっと続いてからカットされます (右)。 その一方で、ボタンではなくテキストがクリップされる場合は、 テキストを収めるスペースをどれくらいにするかに基づいてクリップします (中央)。
シンプルな座標軸に平行なクリップ処理の例の他にも、積み重なっている任意のクワッドにも対応しています。

これは極端なサンプルですが、3D トランスフォームとプロジェクションの導入には、プロジェクションでクリップされるウィジェットは投影空間でクリッピングを実行しなければならないので、 複数の任意のクリップする領域にまとめられることが必須です。
4.16 以前と 4.17 以降の変換ガイド
4.17 でのスレート クリップ処理システムへの変更は、以前のバージョンで使っていた後方互換性を破りました。以下のセクションでは、従来の問題を避けるためのプロジェクトのアップデート方法、 およびプロジェクトでウィジェットのデバッグに使用できるメソッドについて説明します。
ウィジェットのクリップ処理を有効にする
すべての UMG ウィジェットに対して、選択したウィジェットの [Details] パネルの Clipping プロパティを調整することができます。

詳細は「UMG UI Designer を使ってクリップ処理をする」を参照してください。
コードでクリップ処理を有効にするには、EWidgetClipping
のクリップ処理用のプロパティを以下のいずれかのステートにする必要があります。
- Inherit
- ClipToBounds
- ClipToBoundsWithoutIntersecting
- ClipToBoundsAlways
- OnDemand
以下がコードの例です。
SNew( SBorder )
.Clipping(EWidgetClipping::ClipToBounds)
[
...
]
非推奨とする API
以下の API は 4.16 現在、非推奨となっています。プロジェクトでこれらを使用している場合は、今それを使う必要があるのか検討してください。すべてのウィジェットがクリップするわけではないので、 クリップ処理システムでクリップする領域をうまく移動することができるコードは必要なくなりました。
FSlateDrawElement::Make___(...)
- ドローコールごとにクリップする領域をパスする必要はなくなったので、関数コールを削除すれば自動的に新しいバージョンを使えるようになります。SScissorRectBox
- 座標軸に平行にクリップする領域は、どれもシザー領域となったため必要なくなりました。必ず削除し、直下の子ウィジェットでクリップ処理を有効にして、これまで行われていたこのジョブを置き換えてください。
カスタム クリッピング
ウィジェット内でクリップが必要となる場合があります。例えば、SProgressBar
は、その進捗に応じて任意の位置を描画するプログレス バーをクリップする必要があります。クリップ処理を追加するためには、OnPaint
で以下を行います。
OutDrawElements.PushClip(FSlateClippingZone(AllottedGeometry));
//TODO Do your drawing here, or child widget paint calls.
OutDrawElements.PopClip();
FSlateClippingZone
は、既存コードに簡単な規則を可能にするいくつかのメソッドで初期化することができる、ウィンドウ領域の任意のクリップ対象領域です。
Hit Testing を変更するカスタム クリップ処理も必要であれば、以下を設定してクリップする領域を Hit Test Grid 上にプッシュする必要があります。
OutDrawElements.PushClip(FSlateClippingZone(AllottedGeometry));
Args.GetGrid().PushClip(FSlateClippingZone(GetCachedGeometry()));
//TODO Do your drawing here, or child widget paint calls.
OutDrawElements.PopClip();
Args.GetGrid().PopClip();
Hit Test Grid 用のクリッピング領域は、AllotedGeometry ではなくキャッシュ ジオメトリを使います。OnPaint
では、Hit Grid はデスクトップ領域、AllotedGeometry
は画面領域です。
従って、Tick に入ったらジオメトリを使用しなければなりません。
クリップ処理ステートのラップ処理
時々、クリップ処理ステートのあるウィジェットがクリップ処理をしない場合もあります。例えば、SScrollBox
は他のウィジェットと同じくクリップ処理ステートの公式な変更が可能ですが、
SScrollBox を構築すると、
bClippingProxy が
true` に設定されます。スレートがそのウィジェットをレンダリングする時、クリップ処理ステートを無視するため、スレートがそのウィジェットをレンダリングするとクリップ処理ステートを無視します。
内部では、SScrollBox
別のネスト化したウィジェットに情報を送る、あるいは命令されたクリップ処理ステートはすべて実行します。さらに、クリップ処理ステートをユーザーが変更する時、
SScrollBox
が OnClippingChanged
という名前の SWidget
関数をオーバーライドするので、新しいクリップ処理ステートをネスト化されたプライベート ウィジェットにミラーするタイミングが分かります。
カリングの変更
クリップ処理はレンダリング領域で実行されますが、エンジンはまだシンプルなバウンディング ボックスを使ってカリングを実行します。ただし、ボックスはレンダリング トランスフォームされたクリップ対象領域のバウンディング ボックスに基づきます。さらに、クリップ処理とカリングは時間経過と共にさらにニュアンスを帯びるので、カスタム パネルがあって MyClippingRect.IntersectionWith
を使って描画が不可能なウィジェットの特定とカリングを行っている場合、SWidget
関数 IsChildWidgetCulled
を使えるようになりました。以下が例です。
for (int32 ChildIndex = 0; ChildIndex < ArrangedChildren.Num(); ++ChildIndex)
{
FArrangedWidget& CurWidget = ArrangedChildren[ChildIndex];
if (!IsChildWidgetCulled(MyCullingRect, CurWidget))
{
// このウィジェットをペイントします
}
}
OnPaint コールで MyClippingRect
を受け取る場所の名前はすべて MyCullingRect
に変更します。
クリップ処理システムを変更しても、スレートのカリング方法は変更されません。以下の例では、親ウィジェット (青) がクリップする領域外 (緑) でカリングされると、 レンダリングを可能にするトランスフォームが親の範囲の完全に外側にある場合でも、子ウィジェット (黄) はカリングされます。フラグは直接の親ウィジェットによってのみチェックされるので、 クリップ処理プロパティ [Clip to Bounds - Without Intersecting] が有効にされた場合も同じです。


クリップ処理のデバッグ
Widget Reflector はエディタ内で選択したウィジェットのクリップ処理ステートを表示します。

クリップ処理ステートが [On Demand] に設定されていることを表示する [Widget Reflector] を使ってテキスト ブロックが選択されています。
[Widget Reflector] を開くには、ファイル メニューから [Window] > [Developer Tools] > [Widget Reflector] を選択します。
以下は、エディタ内のすべてのウィジェットのクリップ処理およびカリング ステートのデバッグに使用可能なコンソール変数です。
コンソール変数 | 説明 |
---|---|
Slate.ShowClipping | 有効にすると、座標軸に平行にクリップする領域 (シザー領域) は黄色の枠線、ステンシル クリッピング クワッドは赤の枠線が表示されます。 画像をクリックしてフルサイズで表示 |
Slate.DebugCulling | 有効にすると、パネルでのカリングの仕組み、および正しく動作しない原因が分かりやすくなります。GPU のクリップ処理を無効にしますが、そのまま正常に動作し続けるため、クリップする領域外でレンダリングされるものをすべて表示して、期待通りにカリングが行われているかを確認することができます。 |
Slate.EnableDrawEvents | 有効にするとドロー イベントが有効になり、RenderDoc などのデバッグ時にバッチまたはクリップ処理ステートの推移が理解しやすくなります。Debug ビルドの使用時はデフォルトで有効になります。 |