❗️

【UE5】C++を使って今どのWidgetが表示されているのか確認する機構を作る

2024/12/12に公開
2

概要

この記事は一人アドベントカレンダー by ダリアの12日目の記事です。

今回はC++を使ってAddToViewportのコールバックに関数をバインドし、現在何がAddToViewportされているのかを目視で確認できるようにし、備忘録としてやり方をまとめたものになります。

イメージとしてはこういうのを想定してます。

■2024/12/14 追記
ウィジェットリフレクタというデバッグツールがあることを教えていただきました。
やりたいことはこのツールで叶いそうなので自作する必要はなくなりましたが、この記事自体はC++で自作したい人向け(例えば最小限の構成でみたいなど)のために残しておこうと思います。
https://x.com/kiikey4/status/1867373259106451756

環境

UE5.4.4

やり方

今回Viewportに追加/削除されたかどうかを知るために使うのはUGameViewportSubsystem(EngineSubsystem)です。
このSubsystemから追加した時のコールバックOnWidgetAdded、削除したときのコールバックOnWidgetRemovedを使って処理を書いていきます。

今回はEditorSubsystemを継承したクラスを作り、AddToViewportされたら配列に追加するようにし、Removeされたら配列から削除するようにします。

コード

#pragma once

#include "CoreMinimal.h"
#include "EditorSubsystem.h"
#include "Components/Widget.h"
#include "ExampleViewportExtensionSubsystem.generated.h"

UCLASS()
class EXAMPLEVIEWPORTEXTENSION_API UExampleViewportExtensionSubsystem : public UEditorSubsystem
{
	GENERATED_BODY()
private:
	void Initialize(FSubsystemCollectionBase& Collection) override;
	void AddViewport(UWidget* Widget, ULocalPlayer* LocalPlayer);
	void RemoveViewport(UWidget* Widget);
public:
	UPROPERTY(EditAnywhere,BlueprintReadWrite)
	TArray<TObjectPtr<UWidget>> ViewportWidgets;
};


#include "ExampleViewportExtensionSubsystem.h"

#include "Blueprint/GameViewportSubsystem.h"

void UExampleViewportExtensionSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
    auto Subsystem = GEngine->GetEngineSubsystem<UGameViewportSubsystem>();
    Subsystem->OnWidgetAdded.AddUObject(this,&UExampleViewportExtensionSubsystem::AddViewport);
    Subsystem->OnWidgetRemoved.AddUObject(this,&UExampleViewportExtensionSubsystem::RemoveViewport);
    Super::Initialize(Collection);
}

void UExampleViewportExtensionSubsystem::AddViewport(UWidget* Widget, ULocalPlayer* LocalPlayer)
{
    ViewportWidgets.Add(Widget);
}

void UExampleViewportExtensionSubsystem::RemoveViewport(UWidget* Widget)
{
    ViewportWidgets.Remove(Widget);
}

後はEditorUtilityWidgetを作ります。
こういう感じにListViewに現在表示されている分のWidget名を表示してもらうようにします。(ListViewについては前回の記事を御覧いただけると幸いです)

冒頭の表示のようになったら成功です。

今回の記事は以上になります。
ここまで読んでいただきありがとうございました。

Discussion

kiruru002kiruru002

UEditorSubsystemはUObject継承なのでAddUFunctionの代わりにAddUObjectが使えますよ

->OnWidgetAdded.AddUObject(this, &UExampleViewportExtensionSubsystem::AddViewport);

https://dokuro.moe/ue4-cpp-how-to-use-delegate/
これでUFUNCTIONも外せます

ダリアダリア

コメントと情報提供ありがとうございます…!こちらでもその方法で実行するのを確認しましたので記事を修正させていただきました。大変助かりました