ぼっちプログラマのメモ

UE4とかUE5とかについて書いたり書かなかったり。

【UE5】アウトライナーの目玉アイコン(Visibility)をEditorUtilityからONOFFする方法について(SetIsTemporarilyHiddenInEditor)

本記事はUnreal Engine (UE)のカレンダー | Advent Calendar 2023 - Qiita シリーズ5の 5日目の記事です

はじめに


ホグワーツレガシーの開発者による講演「Collision Data in UE5: Practical Tips for Managing Collision Settings & Queries(Unreal Engine 5での衝突データ: 衝突設定とクエリの管理に関する実用的なアドバイス)」にて、「Collision Presetの設定状況に応じて表示ONOFFするEditorUtilityを作ると視覚的に確認できていいぞ」という内容がありました。が、具体的にどうすればいいのかは説明がなかったので試しに作ってみました。


これを作る過程で「アウトライナーの目玉アイコン(Visibility)をEditorUtilityからONOFF処理が欲しくなったので調べた結果を記事にしました。

なお、上述の講演に関しては下記記事にて内容をまとめています。
pafuhana1213.hatenablog.com

アウトライナーの目玉アイコン(Visibility)をEditorUtilityからONOFFする方法について

AActor::SetIsTemporarilyHiddenInEditor関数・ノードを呼ぶだけ!

とだけの解説だと寂しいので、この関数・ノードだと特定した流れについて軽く説明

1. 目玉アイコンにマウスカーソルを合わせた際のツールチップ「Toggles the visibility of this object in the level editor.」でエンジンコードを検索し、下記コードがヒットする

const TSharedRef<SWidget> FSceneOutlinerGutter::ConstructRowWidget(FSceneOutlinerTreeItemRef TreeItem, const STableRow<FSceneOutlinerTreeItemPtr>& Row)
{
	if (TreeItem->ShouldShowVisibilityState())
	{
		return SNew(SHorizontalBox)
			+SHorizontalBox::Slot()
			.AutoWidth()
			.VAlign(VAlign_Center)
			[
				SNew(SVisibilityWidget, SharedThis(this), WeakOutliner, TreeItem, &Row)
				.ToolTipText(LOCTEXT("SceneOutlinerVisibilityToggleTooltip", "Toggles the visibility of this object in the level editor."))
			];
	}
	return SNullWidget::NullWidget;

2. 上記コードを見る限りだと SVisibilityWidget が使われてるようなので、SVisibilityWidgetが定義されてる SceneOutlinerGutter.cppを眺めていると、何やらVisiblityをONOFFしているコードを見つける

void SVisibilityWidget::OnSetItemVisibility(ISceneOutlinerTreeItem& Item, const bool bNewVisibility)
{
	// Apply the same visibility to the children
	Item.OnVisibilityChanged(bNewVisibility);

	if (ShouldPropagateVisibilityChangeOnChildren())
	{
		for (auto& ChildPtr : Item.GetChildren())
		{
			auto Child = ChildPtr.Pin();
			if (Child.IsValid())
			{
				OnSetItemVisibility(*Child, bNewVisibility);
			}
		}
	}
}

3. 上記コードにおけるItem.OnVisibilityChanged(bNewVisibility);がそれっぽかったので実装箇所を眺めていく。

void FActorTreeItem::OnVisibilityChanged(const bool bNewVisibility)
{
	// Save the actor to the transaction buffer to support undo/redo, but do
	// not call Modify, as we do not want to dirty the actor's package and
	// we're only editing temporary, transient values
	SaveToTransactionBuffer(Actor.Get(), false);
	Actor->SetIsTemporarilyHiddenInEditor(!bNewVisibility);
}

4. Actor->SetIsTemporarilyHiddenInEditor !これや!!!!!
docs.unrealengine.com

おしまい(酷い記事だ!)