← SEARCHABLE ARCHIVE
Unreal Engine · 2026-07-04

WidgetライフサイクルとDelegate冗長接続

NativeConstructが再度呼び出されたときに発生する問題

INTERACTIVE READING MODE →

本ブログ作成文は、講義を目指して製作されました。 また、作成された文章の情報も間違っている可能性がありますので、ご注意ください。

UUserWidget::NativeConstruct()は、オブジェクトが最初に作成されたときにちょうど一度だけ呼び出されると考えやすいです。 ただし、ウィジェットが画面から削除されて再度追加されると、Constructが再び呼び出される可能性があります。

Delegate が重複リンクすることができる

void UDailyProblemWidget::NativeConstruct()
{
    Super::NativeConstruct();

    SubmitButton->OnClicked.AddDynamic(
        this,
        &UDailyProblemWidget::HandleSubmit
    );
}

Constructが2回呼び出されると、同じボタンクリックで関数を2回実行できます。 保存、商品の差引、ノードの作成などのロジックであれば、実際のデータが重複して処理されます。

ProjectDTでは、接続する前に同じDelegateを削除するようにまとめました。

if (SubmitButton)
{
    SubmitButton->OnClicked.RemoveDynamic(
        this,
        &UDailyProblemWidget::HandleSubmit
    );

    SubmitButton->OnClicked.AddDynamic(
        this,
        &UDailyProblemWidget::HandleSubmit
    );
}

NativeOnInitializedとNativeConstruct

一度だけ準備する作業はNativeOnInitialized()がより似合うことができる。 画面に入るたびに更新する必要がある値は、NativeConstruct()別のセットアップ関数で処理します。

NativeOnInitialized: オブジェクトの存続期間中に一度
NativeConstruct:Viewに貼り付けられたときに再度呼び出されることがある
NativeDestruct:Viewから落ちたときに呼び出される

ウィジェットプーリングや再利用構造では、オブジェクト生成と画面表示を同じ事象で見てはならない。 ボタン接続、データ初期化、画面更新をそれぞれどの時点にすべきかを分けることが重要である。