レベルに並べた木や岩が、どれも同じ向きで同じ大きさに見える。少しずつ変化を付けたいけれど、1つ選んで回転を変え、次を選んで大きさを変える作業を何度も繰り返している。
こうした作業を、エディタのボタンにまとめられるのが Editor Utility Widget です。ゲームを動かすBlueprintの考え方を使って、自分が制作中に使う小さな道具を作れます。
この記事では、選んだ小物の向きと大きさをまとめて変えるツールを作ります。最初は選択件数を表示するだけのボタンを動かし、そこへ変更処理とUndoを足していきます。
この記事でわかること
- エディタ用ツールと、ゲーム内UIの違い
- ボタンを置き、選択中のActorを取得する手順
- 回転と大きさを、Actorごとに変える組み方
- 一括変更をUndo一回で戻せるようにする方法
Editor Utility Widgetは、制作中に使う道具
Widget は、ボタンや文字を組み合わせた画面の部品です。Editor Utility Widgetは、その仕組みで UEエディタ用のタブ を作ります。ゲーム中のHPバーやポーズメニューを作るUMGと、画面の組み立て方はよく似ています(→ UMG入門)。
今回はゲームのPlayを止めた状態で、レベルに置いたものを編集します。プレイヤーが遊んでいる最中に使うメニューではありません。ツールから変更した配置は、保存すればゲームのレベルにも反映されます。
| 作り方 | 操作する場所 | 向いている用途 |
|---|---|---|
| Editor Utility Widget | 自作のタブに置いたボタンや入力欄 | 値を調整しながら繰り返す作業 |
| Scripted Actions | アセットやActorの右クリックメニュー | 選んだものへ決まった処理を実行する作業 |
Scripted ActionsはEditor Utility Blueprintで作る方式の1つです。アセット用の AssetActionUtility、Actor用の ActorActionUtility など、用途に合う親クラスを使います。この記事では、操作画面を作るEditor Utility Widgetへ絞ります。

アセットとActor、どちらを選んでいる?
同じ木でも、コンテンツブラウザにあるメッシュと、レベルへ置いた1本は別の対象です。
- アセット:木の形などを保存した素材。コンテンツブラウザから選びます。
- Actor:その素材を使ってレベルへ配置したもの。ビューポートやOutlinerから選びます。
木の素材を10本のActorが共有していても、各Actorの向きや大きさは個別に変えられます。今回は配置済みの小物を編集するので、Actor側を取得します。
| ノード | 取得するもの | 提供元 |
|---|---|---|
| Get Selected Assets | コンテンツブラウザで選択中のアセット | Editor Utility Library |
| Get Selected Level Actors | レベルエディタで選択中のActor | Editor Actor Subsystem |
Subsystem は、特定の仕事をまとめて引き受けるUEの機能です。Editor Actor Subsystemは、エディタ上のActorの選択や編集を扱います。まずその窓口を取得し、そこへ「いま選ばれているActorを 教えて」と頼む形になります。

返ってくるのは 配列、つまり複数のActorを順番にまとめた一覧です。後半ではFor Each Loopを使い、一覧の中のActorへ1つずつ処理を行います。
まずは選択件数を表示するボタンを作る
最初から大量の小物を変更する前に、ボタンから選択内容を取得できるか確かめます。
① タブの中身を作る
- コンテンツブラウザで
Content/EditorToolsフォルダを作ります。 - 右クリックから「Editor Utilities → Editor Utility Widget」を選び、
EUW_ScatterToolと名付けます。 - ダブルクリックで開き、DesignerでルートにVertical Boxを置きます。Vertical Boxは、子の部品を縦に並べる入れ物です。すでに別のルートがある場合は、その中へ配置します。
- Vertical Boxの中にButtonを置き、
BtnScatterと名付けます。その子へText Blockを入れ、表示文字を「選択件数を確認」にします。 - Buttonの下、同じVertical Boxの子として別のText Blockを置き、
TxtStatusと名付けます。初期文字を「まだ実行していません」にし、「Is Variable」をオンにします。
Button自体には表示文字がないため、子のText Blockでラベルを作ります。「Is Variable」は、Graphからその部品を指定して文字を書き換えられるようにする設定です。

② ボタンから件数を表示する
Designerで BtnScatter を選び、Detailsの「Events → On Clicked」の「+」を押します。Graphに、ボタンを押すと呼ばれるイベントができます。
- Graphの検索で
Editor Actor Subsystemを探し、取得用のGet Editor Actor Subsystemを置きます。名前の空白などは版によって異なりますが、Return ValueがEditor Actor Subsystemのものを選びます。 - そのReturn Valueからドラッグして
Get Selected Level Actorsを作り、Targetへつなぎます。 On Clickedの白い実行ピンを、Get Selected Level Actorsの実行入力へつなぎます。Subsystemを取得するノードには、白い実行線をつなぎません。- 返ったActor配列から
Lengthを作ります。Lengthは配列にいくつ入っているかを返します。 Format Textに選択:{Count}件と入力し、現れたCountピンへLengthの値をつなぎます。TxtStatusをGetでGraphへ置き、そこからSet Text (Text)を作ります。TargetはTxtStatus、In TextはFormat TextのResultです。- Get Selected Level Actorsの実行出力をSet Textの実行入力へつなぎ、Compileして保存します。
白い線は 処理を進める順番、データの線は どのActorや値を使うか を渡します。Subsystemを取得することと、そのSubsystemに処理を頼むことを分けると、配線を追いやすくなります。

実行の順番も含めると、全体はこうなります。

③ 開いて、小さく動かす
コンテンツブラウザでEUW_ScatterToolを右クリックし、「Run Editor Utility Widget」を選びます。開いたタブはLevel Editorの他のタブと並べて配置できます。
Playを止めた状態で、Outlinerから小物のActorを3つ選び、ボタンを押します。「選択:3件」と出れば、取得と表示はつながっています。選択を1つにしてもう一度押すと1件、選択を外して押すと0件になります。表示が更新されるのは、ボタンを押した時点です。
実践:選んだ小物の向きと大きさを変える
ここから変更処理を足し ます。まずは練習用レベルに、向きが分かる木や岩の Static Mesh Actor を3〜5個だけ置きます。Static Mesh Actorは、形の変わらないメッシュをレベルへ置くためのActorです。素材がなければCubeでも試せますが、回転はDetailsの数値も見て確認します。
今回は次の条件に揃えます。
- 各Actorを他のActorへアタッチせず、独立して置く。
- 初期回転は0、スケールは
(1, 1, 1)。物理シミュレーションは使わない。 - 通常のStatic Mesh Actorを対象にし、Blueprint製のActorやFoliageで塗った草木は対象外とする。
どこを変えるか決める
Yaw は、縦のZ軸を中心に左右へ向きを変える回転です。今回はYawを0〜360度の乱数で決め、PitchとRollは0にします。乱数は、指定した範囲から値を選ぶものです。
スケール は大きさの倍率です。1なら元の大きさ、0.9なら9割、1.1なら1割大きくなります。X・Y・Zへ同じ値を渡すと、縦横の比率を保てます。
このツールは現在値へ倍率を掛け続けるのではなく、回転とスケールを新しい値で置き換えます。 何度押しても大きさが際限なく増える処理にはしません。位置は動かしません。
① Undo用の記録を用意する
これから使うTransact Objectは、これから変えるものの状態を、Undo用に記録する ノードです。Actorの位置・回転・大きさは、根元の部品である Root Component が持っています。そのため、今回の変更ではActorだけでなくRoot Componentも記録します。
さらに一括変更の前後を、次の2つで囲みます。
| ノード | 役割 |
|---|---|
| Begin Transaction | Undo一回で戻す操作のまとまりを始める |
| End Transaction | そのまとまりを閉じる |
Transaction は、ここでは「まとめて取り消す1回分の編集」です。小物を5個変えても、ボタン1回の結果をUndo一回で戻せるようにします。

② Actorを1つ変える関数を作る
EUW_ScatterToolの「My Blueprint → Functions」の「+」で ScatterOne を作ります。関数は、ひとまとまりの処理に名前を付けたものです。今回は「小物1個の向きと大きさを変える」をまとめます。
関数の入力に TargetMesh を追加し、型を Static Mesh ActorのObject Reference にします。これは、どの配置物を変えるかを渡すための入力です。Class Referenceとは区別します。
関数内にFloat(小数を扱う型)のローカル変数 NewScale も作ります。ローカル変数は、その関数の処理中に使う値の置き場所です。
白い実行線を、関数の入口から次の順に接続します。
Transact Object。ObjectへTargetMeshをつなぐ。- もう1つの
Transact Object。TargetMeshから取得したGet Root ComponentのReturn ValueをObjectへつなぐ。 Set Actor Rotation。TargetはTargetMesh、New RotationはMake RotatorのReturn Value。Make RotatorのYawだけにRandom Float in Range(Min 0、Max 360)をつなぎ、RollとPitchは0にする。Set NewScale。値には別のRandom Float in Range(Min 0.9、Max 1.1)をつなぐ。Set Actor Scale 3D。TargetはTargetMesh。Get NewScaleの値をMake VectorのX・Y・Zへ渡し、そのReturn ValueをNew Scale 3Dへつなぐ。
同じ値を3軸に使うことがはっきり分かるように、スケール用の乱数は一度NewScaleへ入れます。Actorごとに関数が呼ばれるので、小物ごとには別の値を選び直します。

前半は「変更前の状態を残して、向きを変える」部分です。続く大きさの変更では、下図のように1つの値を3軸で共有します。図の1.05は、乱数で選ばれた値の一例です。

Make Vectorは、X・Y・Zの3つの数を1つの値にまとめるノードです。その結果をNew Scale 3Dへ渡します。変更対象を渡すTargetとは、別の入力です。

③ ボタンから、選んだ小物を順に変える
最初に作った件数表示を残し、その後へ処理を足します。ここで使う Branch は、条件が成り立つ場合はTrue、成り立たない場合はFalseへ処理を分けるノードです。
- Widgetに
SelectedActorsという変数を作り、型をActorのObject Reference、入れ物を配列にします。 - Get Selected Level Actorsの直後に
Set SelectedActorsを挟み、Return Valueの配列を保存します。件数表示のLengthにも、この配列を使います。 - Set Textの後にBranchを置き、Conditionへ
Length > 0をつなぎます。False側は何もせず終えます。 - True側から
Begin Transactionを呼びます。ContextはEUW_ScatterTool、Descriptionは小物の向きと大きさを変更、Primary Objectは未指定で構いません。 - Begin TransactionのReturn Valueが
0以上かをBranchで確認します。成功側のTrueからFor Each Loopを呼び、ArrayへSelectedActorsをつなぎます。 - Loop Bodyから
Cast To StaticMeshActorを呼び、ObjectへArray Elementをつなぎます。成功側からScatterOneを呼び、TargetMeshへAs Static Mesh Actorをつなぎます。ScatterOne自身のTargetはツールのSelfです。 - For Each Loopの Completed から
End Transactionを呼びます。ループの途中では閉じません。
Castは、取得したActorをStatic Mesh Actorとして扱えるか確かめる処理です。ライトなどを一緒に選んでも、この確認を通らないものは変更しません。Cast Failed側は未接続で構いません。For Each Loopは残りの要素を処理し、最後にCompletedへ進みます。
Begin Transactionが失敗した場合のFalse側は変更へ進めず、TxtStatusへ「変更を開始できませんでした」と表示します。通常のボタン操作では成功する想定ですが、開始できていない状態で変更しないように分けておきます。

最後にボタンのText Blockを「向きと大きさを変える」へ変更し、Compileして保存します。件数表示は 選択した全Actorの数 です。変更した数とは違うため、実践では対象の小物だけを選んで使います。
動作とUndoを確かめる
練習用レベルを保存し、対象の小物だけを選んでボタンを押します。位置はそのままで、向きと大きさが変わるかを見ます。

- ほかの編集を挟まず、Level Editorの「Edit → Undo」を1回実行します。メニューの対象が「小物の向きと大きさを変更」であることを確認し、変更した全対象が元へ戻るかを確かめます。
- もう一度ボタンを押し、新しい組み合わせへ変わるかを見ます。
- 1個を選び直し、DetailsでYawとスケールを確認します。角度は同じ向きを表す負の値などに整理される場合があります。
- スケールのX・Y・Zが同じで、0.9〜1.1に収まっているかを確認します。結果がよければSave Allで保存します。
エディタ用ツールの変更は、Playを止めても自動では戻りません。 Undoを組んで確認するのはそのためです。戻らない場合は、練習用コピーで配線を直してから使います。「保存せず閉じれば必ず元どおり」という前提で大量の変更を進めないようにします。
| 症状 | 確認する場所 |
|---|---|
| 選択が0件になる | Playが停止中か。コンテンツブラウザでなく、レベルのActorを選んでいるか |
| 件数は出るが変わらない | 対象がStatic Mesh Actorか、Cast成功側がScatterOneへつながっているか |
| 向きの違いが分かりにくい | 球や対称な形ではないか。DetailsのRotationでも比較する |
| 1個しか変わらない | Array Elementを対象にし、Loop Bodyから変更しているか |
| 小物が縦や横に潰れる | NewScaleを1回保存し、その同じ値をX・Y・Zへ使っているか |
| Undoで戻らない | BeginとEndで全体を囲んだか。変更前のActorとRoot Componentを記録したか |
小さな実験として、スケール範囲を0.5〜2.0へ広げて試すと、サイズ差がはっきり見えます。試した後はUndoし、値を0.9〜1.1へ戻してCompile・保存します。ツールの値を変えることと、すでに配置物へ加えた変更を戻すことは別です。
おまけ:自分の作業に合わせて育てる
草木を大量に置くなら、標準機能も使う
草木を地形へ塗るように配置するなら、Foliageに回転や大きさをばらつかせる機能があります。今回のツールは、すでに通常のActorとして置いた小物を編集する例です。位置を散らすツールではないため、同じ列へ置いたものは列のまま残ります(→ LandscapeとFoliage)。
元の傾きや大きさを保ちたいなら
今回はPitchとRollを0へ戻し、スケールを絶対値で設定しました。すでに傾けて置いた岩や、大きさを調整した小物へそのまま使うと、その調整も上書きします。元の値を取得して必要な軸だけ変える、初期値を別に残す、といった用途に合わせた変更が次の段階です。
使う前に、対象と結果が見えるようにする
制作向けに育てるなら、選択した名前の一覧、実際に変更する件数、変更後の値のプレビューを加えると扱いやすくなります。今回の取得→一覧を順に処理する形は、その土台になります(→ Array・Set・Map入門)。
エディタの処理とゲー ムの処理を分ける
Editor Utility Widgetはエディタ用です。ゲーム用Blueprintからツールを参照したり、エディタ専用ノードを実行しようとしたりしない構成にします。EditorToolsというフォルダ名は整理用で、名前だけでパッケージ化の扱いが決まるわけではありません。
また、ツールが編集したレベルの配置やアセットは、保存すればゲーム側で使うデータになります。道具は制作中に使い、その道具で整えたデータをゲームへ渡す という関係です(→ パッケージ化入門)。
まとめ
Editor Utility Widgetでボタンを作り、選択中のActorを一覧で取得すると、普段の編集作業をまとめられます。まず件数を表示して対象を確かめ、1個分の処理を関数へまとめ、選んだ小物へ順に適用しました。
少数の小物で変更とUndoが動けば、次は自分が繰り返している作業へ応用できます。対象の取得、変更、結果の確認を分けて作ると、道具を少しずつ育てやすくなります。