【UE4】ブループリントを一切使わずに子ウィジェットを操作する

これはアンリアルエンジンのウィジェットブループリント(以下、WBP)に関する記事です。
使用したアンリアルエンジンのバージョンは 4.25.3
ソースコードのビルドには Visual Studio 2017 を使用しました。

結論から説明

C++ で子ウィジェットを直接操作するには、クラスのヘッダファイルで以下の宣言を行います。

UPROPERTY(EditAnywhere, meta = (BindWidget))
	class ウィジェットクラス* 子ウィジェット名 = nullptr;

UPROPERTY() に meta = (BindWidget) を指定することで、C++ 側で直接操作できるようになります。
BindWidget の両端の () をつけないとコンパイルエラーになります。

ゲームプレイ時にウィジェットを生成すると、子ウィジェット名で指定したメンバ変数に子ウィジェットのポインタが入ります。
ただし、これを指定すると、ブループリント側で使えなくなります。

子ウィジェット名は、ウィジェットブループリント編集画面のデザイナーで設定した名前を指定します。
名前を間違えると初期値の nullptr になるので、子ウィジェットの名前を変更したときは、忘れずにこちらの名前も変更する必要があります

各単語の説明

アンリアルエンジンでは、UI をウィジェットと呼びます。
このウィジェットを扱うシステムを UMG(Unreal Motion Graphics) と呼びます。
ウィジェットブループリント(WBP)は、UI の見た目のデザインと、UI の挙動をブループリントで定義するためのファイルです。

WBP の編集画面を開くと、画面右上に「デザイナー > グラフ」と書かれています。

「デザイナー」で、Image や Text を並べて、ウィジェットの見た目のデザインを行います。
「グラフ」では、ブループリントを使って、ウィジェットの挙動を作ります(色、サイズ、位置などを変更することもできます)。

表題の「子ウィジェト」とは、ウィジェットブループリントのデザイナーに追加した Image や TextBox などのことです。
他の WBP を子ウィジェットとして追加することもできます。

WBP でブループリントを使わない…というのは、グラフ(イベントグラフ)にひとつもノードを置かないという意味です。
デフォルトで、3つのイベントが置かれていますが、それらも一切使用しませんので、削除してしまっても構いません。

グラフにある「クラス設定」は使います。

サンプル用の WBP と C++ コードを作る手順
WBP を新規作成

とりあえず、TestWBPC という名前にしました。

サンプル用 WBP に子ウィジェットを追加

とりあえず、Text と Image を子ウィジェットとして追加します。

最初に Canvas Panel(キャンバスパネル)を置かないと、子ウィジェットをひとつしか追加できなくなります。
複数の子ウィジェットを追加するには、キャンバスパネルを追加して、キャンバスパネルの子としてウィジェットを追加していきます。
なので、Text と Image がキャンバスパネルの子になっています。

追加した Text と Image の名前を下記の通りに変更しました。

Text → Sample_Text
Image → Sample_Image

WBP の親クラス(C++)を追加

WBP に子ウィジェットを追加したので、この WBP の親クラスを追加します。

新規追加 → 新規 C++ クラス を選択。

WBP の親クラスは User Widget(UUserWidget) か、UUserWidget を継承しているクラスを選びます。

C++ ソースコード作成

TestWBPC.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"

#include "TestWBPC.generated.h"

/**
 * 
 */
UCLASS()
class MYPROJECT_API UMyTestWBP : public UUserWidget
{
	GENERATED_BODY()

public:

	virtual void NativeConstruct() override;
	virtual void NativeTick(const FGeometry&, float) override;

	UPROPERTY(EditAnywhere, meta = (BindWidget))
		class UTextBlock* Sample_Text = nullptr;

	UPROPERTY(EditAnywhere, meta = (BindWidget))
		class UImage* Sample_Image = nullptr;
};

TestWBPC.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "TestWBPC.h"

#include "Components/Image.h"
#include "Components/TextBlock.h"
#include "Math/UnrealMathUtility.h"

void UMyTestWBP::NativeConstruct()
{
	Super::NativeConstruct();
	check(this->Sample_Text);
	check(this->Sample_Image);

	FString String(TEXT("dokuro.moe"));
	this->Sample_Text->SetText(FText::FromString(String));
}

void UMyTestWBP::NativeTick(const FGeometry& g, float InDeltaTime)
{
	Super::NativeTick(g, InDeltaTime);

	FVector2D Scale = {  FMath::RandRange(0.1f, 5.0f), FMath::RandRange(0.1f, 10.0f) };
	this->Sample_Image->SetRenderScale(Scale);

	FVector2D Translation = { static_cast<float>(FMath::RandRange(0, 1920)), static_cast<float>(FMath::RandRange(0,1080)) };
	this->Sample_Image->SetRenderTranslation(Translation);

	FLinearColor Color = { FMath::RandRange(0.0f, 1.0f), FMath::RandRange(0.0f, 1.0f), FMath::RandRange(0.0f, 1.0f), FMath::RandRange(0.5f, 1.0f) };
	this->Sample_Image->SetColorAndOpacity(Color);
}
WBP の親クラスを変更

WBP 編集画面に戻って、グラフ → クラス設定 → 詳細 → クラスオプション → 親クラス に、作成したクラスを指定します。

プレイ

うーん…。
なんか物足りないな…。

ちょっと見た目に物足りなさを感じたので、こんな感じの簡単なマテリアルを作って、WBP に設定しました。

↓こんな感じになりました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です