目次
※この記事で使用しているUnrealのVersionは05.3.0 Preview1です。
まだPreview版なので、正式リリース時に記事にある内容と差が出る可能性があります。
※この記事のサンプルプロジェクトは以下URLにアップされています。
サンプルプロジェクト
皆さんはレベルエディタ上で作業をしているときに、「Outlinerウィンドウ増やしたい…」と思ったことはありませんでしょうか?
一応現在のUnrealでは、Outlinerウィンドウは最大4つまで増やすことができます。
UE5からWorldPartitionが入り、Level上に置かれるアクターの数も多くなりがちな今日この頃で、通常のOutlinerだけではなかなか作業がしづらい場面も多くなってくるかと思います。
実は5.2から、Blueprintだけで自分だけのオリジナルOutlinerを作ることができるようになってるんです!うれしいね!🐟
(ただ、5.2だといくつかうまく動作しないものがあるので、5.3以降での使用をお勧めします)
UE5からWorldPartitionが入り、Level上に置かれるアクターの数も多くなりがちな今日この頃で、通常のOutlinerだけではなかなか作業がしづらい場面も多くなってくるかと思います。
そんな中、登場したのがObjectMixer
というEditor専用のWidgetです!
BPだけで独自のOutlinerを作る レベル【★★☆】
ひとまずは、独自Outliner用のEditorUtilityWidgetを作ってみましょう!
ContentBrowser左上のAdd
ボタンから、EditorUtilities
→EditorUtilityWidget
を選択します。
(以降EditorUtilityWidgetはEUWと略す)
そうそう、UE5.3からEditorUtilityWidgetを作成するときに、RootとなるWidgetを最初に設定できるようになりました。
ひとまず、Panel系であれば何でもいいのでStackBox
を使ってみます
(StackBox
はVerticalBox
とHorizontalBox
を任意で切り替えられるものだと思ってください)
※5.2まではCanvasPanel
が暗黙的にデフォルトのRootだったので、5.2までと同じ構造のWidgetを作成したい場合はCanvasPanelを選択しましょう
EUWを作成しましたら、ダブルクリック等でWidgetEditorを開きます。
そして、Palette
ウィンドウからObjecttMixer(Generic)を選びDesignerウィンドウにドラッグ&ドロップします。その後Size
プロパティの部分をFill
とします。
(CanvasPanelを使う方はいい感じにサイズを調整してください)
もうすでにOutlinerっぽい見た目していますね!
ただ、ObjectMixer
ウィジェットそのものにはカスタマイズを行える機能はなく、ただ単にOutlinerのような見た目でアクター等のオブジェクトを表示するためのものです。
これだけではカスタマイズできないため、もう一つBlueprintを作成します。
ContentBrowser左上のAdd
ボタンから、EditorUtilities
→EditorUtilityBlueprint
を選択します。
(以降EditorUtilityBlueprintはEUBPと略す)
すると、親クラスを選択する画面が出てくるかと思いますので、ObjectMixerBlueprintObjectFilter
を選択してください。
このクラスは、先ほど作成したEUWのほうのObjectMixerに設定することができ、このクラスにいくつかの処理をBlueprintで書くことによって、カスタマイズされたOutlinerを作成できます!
EUBPを作成しましたら、ダブルクリック等でBlueprintEditorを開きましょう。
何の変哲もないただのBlueprintですが、オーバーライド可能な関数がいくつかあります。
すべての説明は後程しますので、ひとまずは最低限の実装をしてみます。
まず、GetObjectClassesToFilter
という関数をオーバーライドします。
以下のようにBlueprintを組んでみます。
もう一つ、GetObjectClassesToPlace
という関数をオーバーライドします。
できましたら、一旦ObjectMixerBlueprintObjectFilter
を閉じ、先ほど作成したEUW内のObjectMixerのDetailウィンドウ内のObjectMixerWidgetUserConfig
->DefaultFilterClass
に作成したObjectMixerBlueprintObjectFilter
を設定します。
できましたらEUWを実行します。
EUWのウィンドウ内にあるRunUtilityWidget
ボタンを押します。
↓
先ほどGetObjectClassessToFilter
でDirectionalLight
クラスを設定しましたが、これによってDirectionalLight
のみを表示するOutlinerができました。
また、Widget左上の「+Add」からDirectionalLightを配置することもできます。
GetObjectClassessToPlace
でDirectionalLight
クラスを設定しましたが、これによって「+Add」からDirectionalLight
を配置することができるようになりました。
また、ObjectMixerにはもう一つ大きな特徴があります。
それは、任意のプロパティをカラムとして表示することができ、Widget内で編集することができる、というものです。
試しに、GetObjectClassessToFilter
にActor
を設定します。
その後EUWを実行してから、ItemListやLabelと書かれた部分を右クリックすると、ベースとなる表示可能な項目に加えてActor
が持っている編集可能な単一のプロパティが表示されるかと思います。
任意のプロパティにチェックを入れてみましょう(↓はCanBeDamage
)
プロパティのカラムを表示すると、そのプロパティの値も一緒に表示することができます。
そして、このカラム上でプロパティを編集することができます。とても便利ですね!!
ここで、ObjectMixerウィジェットの各種UIの説明をします。
まとめると、ObjectMixerは
1.任意のクラスのみを表示できる
2.アクター追加ボタンに任意のアクタークラスを設定できる
3.プロパティのカラムを表示し、Widget内で編集することができる
という3つの大きな特徴があります。
これらの特徴を生かして、作業にあった独自Outlinerを作成してみてください!
ObjectMixerBlueprintObjectFilterのオーバーライド関数について
以下がObjectMixerBlueprintObjectFilter
オーバーライド可能な関数とその説明になります。
※尚、プロパティのいくつかは「Set」と呼ばれる型を使用することになります。
使い方は以下をご覧ください。
また、プロパティ名を指定する項目がいくつかありますが、Editor上のUIで表示されている名前ではなくC++で定義されている名前を指定します。
尚、Editor上のプロパティを右クリック→CopyInternalName
を行うことでもC++で定義された名前を取得することができます。
(ただし、一部は特殊なプロパティの構造をしておりこの方法では取得できないプロパティもあります)
GetColumnsToExclude
ここに指定した名前のプロパティは、
ObjectMixer上のカラム表示の選択ができなくなります。
GetColumnsToShowByDefault
「RestoreDefaultColumns」を押した際に表示するプロパティのカラム
GetForceAddedColumns
GetObjectMixerPropertyInheritanceInclusionOptions
にて表示が抑制されているプロパティや、
UPROPERTYマクロがついているがEditor上で見える設定ではないプロパティのカラムを強制的に表示可能にする。
(例えばSceneComponent::RelativeLocation
は通常だと表示できないが、ここに設定することでカラムとして表示できる)
※GetObjectMixerPropertyInheritanceInclusionOptions
にて表示が抑制されているプロパティのほうは、GetObjectClassesToFilter
で指定しているクラスかその親が指定したプロパティを持っている必要がある。
GetObjectClassesToFilter
表示するオブジェクトのクラスを設定する
基本的には、AActor
かUActorComponent
を継承したクラスを指定する
(全表示したいならAActor
やUActorComponent
を指定する)
GetObjectClassesToPlace
ObjectMixerWidget左上の「+Add」ボタンから配置できるアクターのクラスを設定する。
※独自のBP等のクラスは今のところ設定できず、UActorFactory
にてFactoryが定義されているActorクラスのみ配置可能。簡単に言うと、デフォルトでPlaceActors
ウィンドウにあるクラスであれば表示可能。
GetObjectMixerPlacementClassInclusionOptions
配置するアクタークラスでGetObjectClassesToPlace
で指定したクラスを基準に、親クラスや子クラスを含むかどうかを設定することができます(Default=None
で、指定クラスのみが表示される)
詳しくは少し↓の「EObjectMixerInheritanceInclusionOptionsの説明」をご覧ください。
GetObjectMixerPropertyInheritanceInclusionOptions
表示するプロパティのカラムで、GetObjectClassesToFilter
で指定したクラスを基準に、親クラスや子クラスのプロパティを含むかどうかを設定することができます(Default=None
で、指定クラスのみのプロパティが表示される)
詳しくは少し↓の「EObjectMixerInheritanceInclusionOptionsの説明」をご覧ください。
尚、GetObjectMixerPlacementClassInclusionOptions
とGetObjectMixerPropertyInheritanceInclusionOptions
で指定するEObjectMixerInheritanceInclusionOptions
の説明は以下になります。
EObjectMixerInheritanceInclusionOptionsの説明
値 | 説明 |
---|---|
None | 指定したクラスのみ |
IncludeOnlyImmediateParent | 指定したクラスおよびその親クラス(直近の親のみ) |
IncludeOnlyImmediateChildren | 指定したクラスおよびその子クラス(直近の子のみ) |
IncludeOnlyImmediateParentAndChildren | 指定したクラスおよびその親と子クラス(直近の親と子のみ) |
IncludeAllParents | 指定したクラスおよびその親クラス(Uclassとしてたどれる限りのすべての親) |
IncludeAllChildren | 指定したクラスおよびその子クラス(すべての子) |
IncludeAllParentsAndChildren | 指定したクラスおよびその親と子クラス(Uclassとしてたどれる限りのすべての親とすべての子) |
IncludeAllParentsAndOnlyImmediateChildren | 指定したクラスおよびその親と子クラス(Uclassとしてたどれる限りのすべての親と直近の子) |
IncludeOnlyImmediateParentAndAllChildren | 指定したクラスおよびその親と子クラス(直近の親とすべての子) |
GetPropertiesThatRequireListRefresh
指定したプロパティが更新されたときに、ObjectMixerで表示しているObjectのリスト表示を更新をするようにします。
(Property更新時にConstructionScript等でComponent等が生成されたりする場合等に使用したりします)
GetShowTransientObjects
Transientなアクター(保存できないアクター)の表示をするか否かを制御できます(Default=False
)
ShouldIncludeUnsupportedProperties
Trueにすることで、通常は表示されないプロパティ(UPROPERTYでEdit設定されていないもの)や配列・構造体などの単一な値でないプロパティを表示することができます(Default=False
)
※ただし、表示ができてもウィンドウ内で変更できないプロパティもあります。
このあたりの表示できるものが何かを制御している部分が気になる方はSObjectMixerEditorList.cppのSObjectMixerEditorList::AddUniquePropertyColumnInfo
をご覧ください。
現状確認できる不具合のような挙動について レベル【★★★☆】
ObjectMixerを明示的にリフレッシュしたい場合(Filter側の処理を変えた場合等)は、内部的にWidgetをRebuildすればいい→つまりRemoveFromParent
してから再度AddChild
等でWidgetを構築してあげれば、ウィンドウ内の項目が再度作り直されます。
尚、どうやら5.2まではObjectMixerWidget内の設定→ObjectFilterClass
のApply
ボタンでリフレッシュできていたのですが、5.3だと設定の保存はされるがリフレッシュがされないようです
それと、EditorUtilityWidget上にObjectMixerウィジェットを配置すると、ContentBrowserで右クリックメニューと変数などのプルダウンで該当のEUWが含まれるような条件で、メニューやプルダウンが表示されない現象が起きます。
これは、ObjectMixerウィジェットが表示される際に「検索ボックスをフォーカスする」というような処理が入っており(SObjectMixerEditorList::Construct
にて固定値で定義SSceneOutliner::Tick
内で判定)この処理が行われると開かれているメニューなどのWidgetが閉じられてしまいます。(FSlateApplication::RequestDestroyWindow
でクローズ)
ContentBrowser内でウィジェットにフォーカスを充てると毎フレームWidgetのプレビューがされ、結果的に毎フレームメニューが閉じる処理が行われます。プルダウンの場合は表示時にプレビューがされます。
これを回避するには、WidgetEditor内のObjectMixerウィジェットの目玉の表示 (EditorVisibility)を閉じておきましょう。
こうすることでプレビュー時にObjectMixerウィジェットのプレビューは走らないので意図しないEditorのメニュー等のWidgetのクローズを避けることができます。
まあこのあたりは今後のアップデート何かしら改善が入るんじゃないかなぁと思います(まだ入ったばかりですし)
※追記:5.3.2では、右クリックメニューが表示されない問題は修正されているようでした。
ちょいたし-Place機能から独自のBPアクターを配置できるようにする レベル【★★★☆】
さて、Outlinerとしての機能に関してはかなり充実した拡張ができるので、とても使えるかなと思いますが、せっかくObjectMixerウィジェットの左上にあるAddボタンから追加できるアクターをフィルターできるのに、登録して表示できるアクターはActorFactoryというクラスを1クラスごとにC++で定義する必要があります。
独自のBPが追加出来たらいいのに…ということで、そういった機能を持つプラグインを簡単にですが作ってみました(サンプルプロジェクトに入っているので、良ければご覧ください)
・使い方
プラグインで独自に定義した、UActorFactoryBPClass
というクラスをEditorUtilityBlueprintで継承します。
作成したBPを開き、ActorClass
というプロパティに任意のBPアクタークラスを選択します。
その後プラグインフォルダの、/CustomObjectMixerPlaceClass/DA_ActorClassList
というDataAssetを開きます。
BPActorFactoriesという項目に先ほど作成したEUBPを設定します。
あとはObjectMixerFilterクラスの、GetObjectClassessToPlace
に指定したActorクラスを設定します。
最後にEditorを再起動することで使えるようになります。
具体的な実装を見たい場合はプロジェクトをダウンロードしてみてください。
※ノリで作ったものなので、Engineアップデートでの動作保証やつくり的な部分の甘さ(参照のさせ方とか)はまああると思います。あくまでサンプルですので、実用的なものはご自身で作成していただければと思います。
毎度粗末な感じですが以上となります。
※この記事のサンプルプロジェクトは以下URLにアップされています。
サンプルプロジェクト